diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 08eb2367a8fba1..1f550660b77984 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -496,7 +496,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) break; case GT_PINVOKE_PROLOG: - noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & ~fullIntArgRegMask()) == 0); + noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & + ~fullIntArgRegMask(compiler->info.compCallConv)) == 0); #ifdef PSEUDORANDOM_NOP_INSERTION // the runtime side requires the codegen here to be consistent diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 8f0484582550a4..c2d1d3c2e90bcb 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2895,9 +2895,9 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere else // we are doing the integer registers { noway_assert(argMax <= MAX_REG_ARG); - if (hasFixedRetBuffReg()) + if (hasFixedRetBuffReg(compiler->info.compCallConv)) { - fixedRetBufIndex = theFixedRetBuffArgNum(); + fixedRetBufIndex = theFixedRetBuffArgNum(compiler->info.compCallConv); // We have an additional integer register argument when hasFixedRetBuffReg() is true argMax = fixedRetBufIndex + 1; assert(argMax == (MAX_REG_ARG + 1)); @@ -3105,7 +3105,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere slotRegType = compiler->GetEightByteType(structDesc, slotCounter); } - regArgNum = genMapRegNumToRegArgNum(regNum, slotRegType); + regArgNum = genMapRegNumToRegArgNum(regNum, slotRegType, compiler->info.compCallConv); if ((!doingFloat && (structDesc.IsIntegralSlot(slotCounter))) || (doingFloat && (structDesc.IsSseSlot(slotCounter)))) @@ -3139,7 +3139,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere #endif // defined(UNIX_AMD64_ABI) { // Bingo - add it to our table - regArgNum = genMapRegNumToRegArgNum(varDsc->GetArgReg(), regType); + regArgNum = genMapRegNumToRegArgNum(varDsc->GetArgReg(), regType, compiler->info.compCallConv); slots = 1; if (TargetArchitecture::IsArm32 || @@ -3202,7 +3202,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere for (int i = 0; i < slots; i++) { regType = regArgTab[regArgNum + i].type; - regNumber regNum = genMapRegArgNumToRegNum(regArgNum + i, regType); + regNumber regNum = genMapRegArgNumToRegNum(regArgNum + i, regType, compiler->info.compCallConv); #if !defined(UNIX_AMD64_ABI) assert((i > 0) || (regNum == varDsc->GetArgReg())); @@ -3343,7 +3343,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere noway_assert(!regArgTab[argNum].stackArg); var_types regType = regArgTab[argNum].type; - regNumber regNum = genMapRegArgNumToRegNum(argNum, regType); + regNumber regNum = genMapRegArgNumToRegNum(argNum, regType, compiler->info.compCallConv); regNumber destRegNum = REG_NA; if (varTypeIsPromotable(varDsc) && @@ -3423,7 +3423,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere if (genRegMask(destRegNum) & regArgMaskLive) { /* we are trashing a live argument register - record it */ - unsigned destRegArgNum = genMapRegNumToRegArgNum(destRegNum, regType); + unsigned destRegArgNum = genMapRegNumToRegArgNum(destRegNum, regType, compiler->info.compCallConv); noway_assert(destRegArgNum < argMax); regArgTab[destRegArgNum].trashBy = argNum; } @@ -3570,7 +3570,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere noway_assert(genTypeSize(storeType) == TARGET_POINTER_SIZE); #endif // TARGET_X86 - regNumber srcRegNum = genMapRegArgNumToRegNum(argNum, storeType); + regNumber srcRegNum = genMapRegArgNumToRegNum(argNum, storeType, compiler->info.compCallConv); // Stack argument - if the ref count is 0 don't care about it @@ -3789,7 +3789,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere assert(xtraReg != REG_NA); - regNumber begRegNum = genMapRegArgNumToRegNum(begReg, destMemType); + regNumber begRegNum = genMapRegArgNumToRegNum(begReg, destMemType, compiler->info.compCallConv); GetEmitter()->emitIns_Mov(insCopy, size, xtraReg, begRegNum, /* canSkip */ false); assert(!genIsValidIntReg(xtraReg) || !genIsValidFloatReg(begRegNum)); @@ -3802,8 +3802,8 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere { /* mov dest, src */ - regNumber destRegNum = genMapRegArgNumToRegNum(destReg, destMemType); - regNumber srcRegNum = genMapRegArgNumToRegNum(srcReg, destMemType); + regNumber destRegNum = genMapRegArgNumToRegNum(destReg, destMemType, compiler->info.compCallConv); + regNumber srcRegNum = genMapRegArgNumToRegNum(srcReg, destMemType, compiler->info.compCallConv); GetEmitter()->emitIns_Mov(insCopy, size, destRegNum, srcRegNum, /* canSkip */ false); assert(!genIsValidIntReg(destRegNum) || !genIsValidFloatReg(srcRegNum)); @@ -3855,7 +3855,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere /* move the dest reg (begReg) in the extra reg */ - regNumber destRegNum = genMapRegArgNumToRegNum(destReg, destMemType); + regNumber destRegNum = genMapRegArgNumToRegNum(destReg, destMemType, compiler->info.compCallConv); GetEmitter()->emitIns_Mov(insCopy, size, destRegNum, xtraReg, /* canSkip */ false); assert(!genIsValidIntReg(destRegNum) || !genIsValidFloatReg(xtraReg)); @@ -3913,7 +3913,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere assert(varDsc->lvIsHfa()); assert((argNum >= firstArgNum) && (argNum <= lastArgNum)); - assert(destRegNum == genMapRegArgNumToRegNum(argNum, regType)); + assert(destRegNum == genMapRegArgNumToRegNum(argNum, regType, compiler->info.compCallConv)); // Pass 0: move the conflicting part; Pass1: insert everything else // @@ -3921,8 +3921,9 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere { for (unsigned currentArgNum = firstArgNum; currentArgNum <= lastArgNum; currentArgNum++) { - const regNumber regNum = genMapRegArgNumToRegNum(currentArgNum, regType); - bool insertArg = + const regNumber regNum = + genMapRegArgNumToRegNum(currentArgNum, regType, compiler->info.compCallConv); + bool insertArg = ((pass == 0) && (currentArgNum == argNum)) || ((pass == 1) && (currentArgNum != argNum)); if (insertArg) @@ -3964,7 +3965,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere varNum = regArgTab[argNum].varNum; varDsc = compiler->lvaGetDesc(varNum); const var_types regType = regArgTab[argNum].type; - const regNumber regNum = genMapRegArgNumToRegNum(argNum, regType); + const regNumber regNum = genMapRegArgNumToRegNum(argNum, regType, compiler->info.compCallConv); const var_types varRegType = varDsc->GetRegisterType(); #if defined(UNIX_AMD64_ABI) @@ -4128,7 +4129,8 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere { argRegCount = 2; int nextArgNum = argNum + 1; - regNumber nextRegNum = genMapRegArgNumToRegNum(nextArgNum, regArgTab[nextArgNum].type); + regNumber nextRegNum = + genMapRegArgNumToRegNum(nextArgNum, regArgTab[nextArgNum].type, compiler->info.compCallConv); noway_assert(regArgTab[nextArgNum].varNum == varNum); // Emit a shufpd with a 0 immediate, which preserves the 0th element of the dest reg // and moves the 0th element of the src reg into the 1st element of the dest reg. @@ -4155,8 +4157,9 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere { int nextArgNum = argNum + i; LclVarDsc* fieldVarDsc = compiler->lvaGetDesc(varDsc->lvFieldLclStart + i); - regNumber nextRegNum = genMapRegArgNumToRegNum(nextArgNum, regArgTab[nextArgNum].type); - destRegNum = fieldVarDsc->GetRegNum(); + regNumber nextRegNum = genMapRegArgNumToRegNum(nextArgNum, regArgTab[nextArgNum].type, + compiler->info.compCallConv); + destRegNum = fieldVarDsc->GetRegNum(); noway_assert(regArgTab[nextArgNum].varNum == varNum); noway_assert(genIsValidFloatReg(nextRegNum)); noway_assert(genIsValidFloatReg(destRegNum)); @@ -4177,7 +4180,8 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere int nextArgNum = argNum + i; regArgElem* nextArgElem = ®ArgTab[nextArgNum]; var_types nextArgType = nextArgElem->type; - regNumber nextRegNum = genMapRegArgNumToRegNum(nextArgNum, nextArgType); + regNumber nextRegNum = + genMapRegArgNumToRegNum(nextArgNum, nextArgType, compiler->info.compCallConv); noway_assert(nextArgElem->varNum == varNum); noway_assert(genIsValidFloatReg(nextRegNum)); noway_assert(genIsValidFloatReg(destRegNum)); @@ -4197,7 +4201,8 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere int nextArgNum = argNum + regSlot; assert(!regArgTab[nextArgNum].processed); regArgTab[nextArgNum].processed = true; - regNumber nextRegNum = genMapRegArgNumToRegNum(nextArgNum, regArgTab[nextArgNum].type); + regNumber nextRegNum = + genMapRegArgNumToRegNum(nextArgNum, regArgTab[nextArgNum].type, compiler->info.compCallConv); regArgMaskLive &= ~genRegMask(nextRegNum); } #endif // FEATURE_MULTIREG_ARGS @@ -7926,12 +7931,32 @@ void CodeGen::genStructReturn(GenTree* treeNode) toReg = retTypeDesc.GetABIReturnReg(1, compiler->info.compCallConv); GetEmitter()->emitIns_R_S(ins_Load(type), emitTypeSize(type), toReg, lclNode->GetLclNum(), offset); } -#else // !TARGET_LOONGARCH64 && !TARGET_RISCV64 +#else // !TARGET_LOONGARCH64 && !TARGET_RISCV64 + +#ifdef SWIFT_SUPPORT + const uint32_t* offsets = nullptr; + if (compiler->info.compCallConv == CorInfoCallConvExtension::Swift) + { + CORINFO_CLASS_HANDLE retTypeHnd = compiler->info.compMethodInfo->args.retTypeClass; + const CORINFO_SWIFT_LOWERING* lowering = compiler->GetSwiftLowering(retTypeHnd); + assert(!lowering->byReference && (regCount == lowering->numLoweredElements)); + offsets = lowering->offsets; + } +#endif + int offset = 0; for (unsigned i = 0; i < regCount; ++i) { var_types type = retTypeDesc.GetReturnRegType(i); regNumber toReg = retTypeDesc.GetABIReturnReg(i, compiler->info.compCallConv); + +#ifdef SWIFT_SUPPORT + if (offsets != nullptr) + { + offset = offsets[i]; + } +#endif + GetEmitter()->emitIns_R_S(ins_Load(type), emitTypeSize(type), toReg, lclNode->GetLclNum(), offset); offset += genTypeSize(type); } diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index 9d84acbcca3a1b..a99199aedc634c 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -4941,7 +4941,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) break; case GT_PINVOKE_PROLOG: - noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & ~fullIntArgRegMask()) == 0); + noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & + ~fullIntArgRegMask(compiler->info.compCallConv)) == 0); // the runtime side requires the codegen here to be consistent #ifdef PSEUDORANDOM_NOP_INSERTION diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 291a688d0968c9..87745fabe3e04b 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -5054,7 +5054,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) break; case GT_PINVOKE_PROLOG: - noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & ~fullIntArgRegMask()) == 0); + noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & + ~fullIntArgRegMask(compiler->info.compCallConv)) == 0); // the runtime side requires the codegen here to be consistent #ifdef PSEUDORANDOM_NOP_INSERTION @@ -8154,7 +8155,7 @@ void CodeGen::genFnPrologCalleeRegArgs() { if (genIsValidIntReg(varDsc->GetArgReg())) { - assert(isValidIntArgReg(varDsc->GetArgReg())); + assert(isValidIntArgReg(varDsc->GetArgReg(), compiler->info.compCallConv)); regArg[varDsc->GetArgReg() - REG_ARG_FIRST] = varDsc->GetArgReg(); regArgInit[varDsc->GetArgReg() - REG_ARG_FIRST] = varDsc->GetArgInitReg(); regArgAttr[varDsc->GetArgReg() - REG_ARG_FIRST] = @@ -8404,10 +8405,11 @@ void CodeGen::genFnPrologCalleeRegArgs() { for (int i = MAX_REG_ARG + MAX_FLOAT_REG_ARG - 1; i >= 0; i--) { - if (regArg[i] != REG_NA && !isValidIntArgReg(regArgInit[i]) && !isValidFloatArgReg(regArgInit[i])) + if (regArg[i] != REG_NA && !isValidIntArgReg(regArgInit[i], compiler->info.compCallConv) && + !isValidFloatArgReg(regArgInit[i])) { assert(regArg[i] != regArgInit[i]); - assert(isValidIntArgReg(regArg[i]) || isValidFloatArgReg(regArg[i])); + assert(isValidIntArgReg(regArg[i], compiler->info.compCallConv) || isValidFloatArgReg(regArg[i])); GetEmitter()->emitIns_Mov(regArgAttr[i], regArgInit[i], regArg[i], false); @@ -8447,9 +8449,10 @@ void CodeGen::genFnPrologCalleeRegArgs() assert(cur != indexList[count2] && "Attempt to move several values on same register."); } assert(cur < MAX_REG_ARG + MAX_FLOAT_REG_ARG); - assert(isValidIntArgReg(regArg[cur]) || isValidFloatArgReg(regArg[cur])); + assert(isValidIntArgReg(regArg[cur], compiler->info.compCallConv) || + isValidFloatArgReg(regArg[cur])); - if (isValidIntArgReg(regArgInit[cur])) + if (isValidIntArgReg(regArgInit[cur], compiler->info.compCallConv)) { cur = regArgInit[cur] - REG_ARG_FIRST; } diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 8384d2b337daf5..47ce1fea52d784 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -2171,7 +2171,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) #endif // !FEATURE_EH_FUNCLETS case GT_PINVOKE_PROLOG: - noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & ~fullIntArgRegMask()) == 0); + noway_assert(((gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur) & + ~fullIntArgRegMask(compiler->info.compCallConv)) == 0); #ifdef PSEUDORANDOM_NOP_INSERTION // the runtime side requires the codegen here to be consistent diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index f0214b3225e4ec..84324b5e302592 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7990,7 +7990,6 @@ class Compiler public: regNumber raUpdateRegStateForArg(RegState* regState, LclVarDsc* argDsc); - void raCheckValidIntParamReg(LclVarDsc* dsc, regNumber inArgReg); void raMarkStkVars(); diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 359adc030f8083..432a435c98919d 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -3292,11 +3292,11 @@ inline int getJitStressLevel() * we return the fixed return buffer register */ -inline regNumber genMapIntRegArgNumToRegNum(unsigned argNum) +inline regNumber genMapIntRegArgNumToRegNum(unsigned argNum, CorInfoCallConvExtension callConv) { - if (hasFixedRetBuffReg() && (argNum == theFixedRetBuffArgNum())) + if (hasFixedRetBuffReg(callConv) && (argNum == theFixedRetBuffArgNum(callConv))) { - return theFixedRetBuffReg(); + return theFixedRetBuffReg(callConv); } assert(argNum < ArrLen(intArgRegs)); @@ -3316,7 +3316,7 @@ inline regNumber genMapFloatRegArgNumToRegNum(unsigned argNum) #endif } -__forceinline regNumber genMapRegArgNumToRegNum(unsigned argNum, var_types type) +__forceinline regNumber genMapRegArgNumToRegNum(unsigned argNum, var_types type, CorInfoCallConvExtension callConv) { if (varTypeUsesFloatArgReg(type)) { @@ -3324,7 +3324,7 @@ __forceinline regNumber genMapRegArgNumToRegNum(unsigned argNum, var_types type) } else { - return genMapIntRegArgNumToRegNum(argNum); + return genMapIntRegArgNumToRegNum(argNum, callConv); } } @@ -3379,9 +3379,9 @@ __forceinline regMaskTP genMapArgNumToRegMask(unsigned argNum, var_types type) * If we have a fixed return buffer register we return theFixedRetBuffArgNum */ -inline unsigned genMapIntRegNumToRegArgNum(regNumber regNum) +inline unsigned genMapIntRegNumToRegArgNum(regNumber regNum, CorInfoCallConvExtension callConv) { - assert(genRegMask(regNum) & fullIntArgRegMask()); + assert(genRegMask(regNum) & fullIntArgRegMask(callConv)); switch (regNum) { @@ -3417,9 +3417,9 @@ inline unsigned genMapIntRegNumToRegArgNum(regNumber regNum) #endif default: // Check for the Arm64 fixed return buffer argument register - if (hasFixedRetBuffReg() && (regNum == theFixedRetBuffReg())) + if (hasFixedRetBuffReg(callConv) && (regNum == theFixedRetBuffReg(callConv))) { - return theFixedRetBuffArgNum(); + return theFixedRetBuffArgNum(callConv); } else { @@ -3477,7 +3477,7 @@ inline unsigned genMapFloatRegNumToRegArgNum(regNumber regNum) #endif // !arm } -inline unsigned genMapRegNumToRegArgNum(regNumber regNum, var_types type) +inline unsigned genMapRegNumToRegArgNum(regNumber regNum, var_types type, CorInfoCallConvExtension callConv) { if (varTypeUsesFloatArgReg(type)) { @@ -3485,7 +3485,7 @@ inline unsigned genMapRegNumToRegArgNum(regNumber regNum, var_types type) } else { - return genMapIntRegNumToRegArgNum(regNum); + return genMapIntRegNumToRegArgNum(regNum, callConv); } } diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 90677f8f4975c1..a8374adbe0a22c 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -1808,24 +1808,15 @@ regNumber CallArgs::GetCustomRegister(Compiler* comp, CorInfoCallConvExtension c return REG_LNGARG_HI; #endif case WellKnownArg::RetBuffer: - if (hasFixedRetBuffReg()) + if (hasFixedRetBuffReg(cc)) { // Windows does not use fixed ret buff arg for instance calls, but does otherwise. if (!TargetOS::IsWindows || !callConvIsInstanceMethodCallConv(cc)) { - return theFixedRetBuffReg(); + return theFixedRetBuffReg(cc); } } -#if defined(TARGET_AMD64) && defined(SWIFT_SUPPORT) - // TODO-Cleanup: Unify this with hasFixedRetBuffReg. That will - // likely be necessary for the reverse pinvoke support regardless. - if (cc == CorInfoCallConvExtension::Swift) - { - return REG_SWIFT_ARG_RET_BUFF; - } -#endif - break; case WellKnownArg::VirtualStubCell: @@ -13223,8 +13214,9 @@ void Compiler::gtGetArgMsg(GenTreeCall* call, CallArg* arg, char* bufp, unsigned } else { - unsigned lastRegNum = genMapIntRegNumToRegArgNum(firstReg) + arg->AbiInfo.NumRegs - 1; - lastReg = genMapIntRegArgNumToRegNum(lastRegNum); + unsigned lastRegNum = + genMapIntRegNumToRegArgNum(firstReg, call->GetUnmanagedCallConv()) + arg->AbiInfo.NumRegs - 1; + lastReg = genMapIntRegArgNumToRegNum(lastRegNum, call->GetUnmanagedCallConv()); } sprintf_s(bufp, bufLength, " %s%c%s out+%02x", compRegVarName(firstReg), separator, compRegVarName(lastReg), arg->AbiInfo.ByteOffset); @@ -13287,8 +13279,9 @@ void Compiler::gtGetLateArgMsg(GenTreeCall* call, CallArg* arg, char* bufp, unsi } else { - unsigned lastRegNum = genMapIntRegNumToRegArgNum(firstReg) + arg->AbiInfo.NumRegs - 1; - lastReg = genMapIntRegArgNumToRegNum(lastRegNum); + unsigned lastRegNum = + genMapIntRegNumToRegArgNum(firstReg, call->GetUnmanagedCallConv()) + arg->AbiInfo.NumRegs - 1; + lastReg = genMapIntRegArgNumToRegNum(lastRegNum, call->GetUnmanagedCallConv()); } sprintf_s(bufp, bufLength, " %s%c%s out+%02x", compRegVarName(firstReg), separator, compRegVarName(lastReg), arg->AbiInfo.ByteOffset); diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index e6833a348b521a..daf31d671beb19 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -4577,7 +4577,7 @@ struct CallArgABIInformation bool IsMismatchedArgType() const { #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - return isValidIntArgReg(GetRegNum()) && varTypeUsesFloatReg(ArgType); + return genIsValidIntReg(GetRegNum()) && varTypeUsesFloatReg(ArgType); #else return false; #endif // TARGET_LOONGARCH64 || TARGET_RISCV64 diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 5cfbd8abd22704..6ee822ec226f67 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -169,6 +169,28 @@ void Compiler::lvaInitTypeRef() info.compRetBuffArg = BAD_VAR_NUM; } +#if defined(DEBUG) && defined(SWIFT_SUPPORT) + if (verbose && (info.compCallConv == CorInfoCallConvExtension::Swift) && varTypeIsStruct(info.compRetType)) + { + CORINFO_CLASS_HANDLE retTypeHnd = info.compMethodInfo->args.retTypeClass; + const CORINFO_SWIFT_LOWERING* lowering = GetSwiftLowering(retTypeHnd); + if (lowering->byReference) + { + printf("Swift compilation returns %s by reference\n", typGetObjLayout(retTypeHnd)->GetClassName()); + } + else + { + printf("Swift compilation returns %s as %d primitive(s) in registers\n", + typGetObjLayout(retTypeHnd)->GetClassName(), lowering->numLoweredElements); + for (size_t i = 0; i < lowering->numLoweredElements; i++) + { + printf(" [%zu] @ +%02u: %s\n", i, lowering->offsets[i], + varTypeName(JitType2PreciseVarType(lowering->loweredElements[i]))); + } + } + } +#endif + /* There is a 'hidden' cookie pushed last when the calling convention is varargs */ @@ -494,7 +516,8 @@ void Compiler::lvaInitThisPtr(InitVarDscInfo* varDscInfo) varDsc->lvIsRegArg = 1; noway_assert(varDscInfo->intRegArgNum == 0); - varDsc->SetArgReg(genMapRegArgNumToRegNum(varDscInfo->allocRegArg(TYP_INT), varDsc->TypeGet())); + varDsc->SetArgReg( + genMapRegArgNumToRegNum(varDscInfo->allocRegArg(TYP_INT), varDsc->TypeGet(), info.compCallConv)); #if FEATURE_MULTIREG_ARGS varDsc->SetOtherArgReg(REG_NA); #endif @@ -525,16 +548,16 @@ void Compiler::lvaInitRetBuffArg(InitVarDscInfo* varDscInfo, bool useFixedRetBuf varDsc->lvIsParam = 1; varDsc->lvIsRegArg = 0; - if (useFixedRetBufReg && hasFixedRetBuffReg()) + if (useFixedRetBufReg && hasFixedRetBuffReg(info.compCallConv)) { varDsc->lvIsRegArg = 1; - varDsc->SetArgReg(theFixedRetBuffReg()); + varDsc->SetArgReg(theFixedRetBuffReg(info.compCallConv)); } else if (varDscInfo->canEnreg(TYP_INT)) { varDsc->lvIsRegArg = 1; unsigned retBuffArgNum = varDscInfo->allocRegArg(TYP_INT); - varDsc->SetArgReg(genMapIntRegArgNumToRegNum(retBuffArgNum)); + varDsc->SetArgReg(genMapIntRegArgNumToRegNum(retBuffArgNum, info.compCallConv)); } #if FEATURE_MULTIREG_ARGS @@ -542,7 +565,7 @@ void Compiler::lvaInitRetBuffArg(InitVarDscInfo* varDscInfo, bool useFixedRetBuf #endif varDsc->lvOnFrame = true; // The final home for this incoming register might be our local stack frame - assert(!varDsc->lvIsRegArg || isValidIntArgReg(varDsc->GetArgReg())); + assert(!varDsc->lvIsRegArg || isValidIntArgReg(varDsc->GetArgReg(), info.compCallConv)); #ifdef DEBUG if (varDsc->lvIsRegArg && verbose) @@ -1007,17 +1030,19 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un #ifdef TARGET_ARM64 if (argType == TYP_STRUCT) { - varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, TYP_I_IMPL)); + varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, TYP_I_IMPL, info.compCallConv)); if (cSlots == 2) { - varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_I_IMPL)); + varDsc->SetOtherArgReg( + genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_I_IMPL, info.compCallConv)); varDsc->lvIsMultiRegArg = true; } } #elif defined(UNIX_AMD64_ABI) if (varTypeIsStruct(argType)) { - varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, firstEightByteType)); + varDsc->SetArgReg( + genMapRegArgNumToRegNum(firstAllocatedRegArgNum, firstEightByteType, info.compCallConv)); // If there is a second eightbyte, get a register for it too and map the arg to the reg number. if (structDesc.eightByteCount >= 2) @@ -1029,7 +1054,8 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un if (secondEightByteType != TYP_UNDEF) { - varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, secondEightByteType)); + varDsc->SetOtherArgReg( + genMapRegArgNumToRegNum(secondAllocatedRegArgNum, secondEightByteType, info.compCallConv)); } } #elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) @@ -1037,12 +1063,14 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un { if (argRegTypeInStruct1 != TYP_UNKNOWN) { - varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argRegTypeInStruct1)); + varDsc->SetArgReg( + genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argRegTypeInStruct1, info.compCallConv)); varDsc->lvIs4Field1 = (genTypeSize(argRegTypeInStruct1) == 4) ? 1 : 0; if (argRegTypeInStruct2 != TYP_UNKNOWN) { secondAllocatedRegArgNum = varDscInfo->allocRegArg(argRegTypeInStruct2, 1); - varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, argRegTypeInStruct2)); + varDsc->SetOtherArgReg( + genMapRegArgNumToRegNum(secondAllocatedRegArgNum, argRegTypeInStruct2, info.compCallConv)); varDsc->lvIs4Field2 = (genTypeSize(argRegTypeInStruct2) == 4) ? 1 : 0; } else if (cSlots > 1) @@ -1062,36 +1090,38 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un } else { - varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, TYP_I_IMPL)); + varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, TYP_I_IMPL, info.compCallConv)); if (cSlots == 2) { - varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_I_IMPL)); + varDsc->SetOtherArgReg( + genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_I_IMPL, info.compCallConv)); } } } #else // ARM32 if (varTypeIsStruct(argType)) { - varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, TYP_I_IMPL)); + varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, TYP_I_IMPL, info.compCallConv)); } #endif // ARM32 else #endif // FEATURE_MULTIREG_ARGS { - varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argType)); + varDsc->SetArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argType, info.compCallConv)); } #ifdef TARGET_ARM if (varDsc->TypeGet() == TYP_LONG) { - varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT)); + varDsc->SetOtherArgReg( + genMapRegArgNumToRegNum(firstAllocatedRegArgNum + 1, TYP_INT, info.compCallConv)); } #if FEATURE_FASTTAILCALL // Check if arg was split between registers and stack. if (varTypeUsesIntReg(argType)) { - unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg()); + unsigned firstRegArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg(), info.compCallConv); unsigned lastRegArgNum = firstRegArgNum + cSlots - 1; if (lastRegArgNum >= varDscInfo->maxIntRegArgNum) { @@ -1122,7 +1152,8 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un else { printf("firstEightByte: %s", - getRegName(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, firstEightByteType))); + getRegName(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, firstEightByteType, + info.compCallConv))); } if (secondEightByteType == TYP_UNDEF) @@ -1132,7 +1163,8 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un else { printf(", secondEightByte: %s", - getRegName(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, secondEightByteType))); + getRegName(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, secondEightByteType, + info.compCallConv))); } } else @@ -1146,7 +1178,8 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un else { printf("first: %s", - getRegName(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argRegTypeInStruct1))); + getRegName(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argRegTypeInStruct1, + info.compCallConv))); } if (argRegTypeInStruct2 == TYP_UNKNOWN) { @@ -1155,7 +1188,8 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un else { printf(", second: %s", - getRegName(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, argRegTypeInStruct2))); + getRegName(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, argRegTypeInStruct2, + info.compCallConv))); } } else @@ -1164,7 +1198,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un assert(varTypeUsesFloatReg(argType) || varTypeUsesIntReg(argType)); bool isFloat = varTypeUsesFloatReg(argType); - unsigned regArgNum = genMapRegNumToRegArgNum(varDsc->GetArgReg(), argType); + unsigned regArgNum = genMapRegNumToRegArgNum(varDsc->GetArgReg(), argType, info.compCallConv); for (unsigned ix = 0; ix < cSlots; ix++, regArgNum++) { @@ -1187,8 +1221,9 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un if (argType == TYP_DOUBLE) { // Print both registers, just to be clear - printf("%s/%s", getRegName(genMapRegArgNumToRegNum(regArgNum, argType)), - getRegName(genMapRegArgNumToRegNum(regArgNum + 1, argType))); + printf("%s/%s", + getRegName(genMapRegArgNumToRegNum(regArgNum, argType, info.compCallConv)), + getRegName(genMapRegArgNumToRegNum(regArgNum + 1, argType, info.compCallConv))); // doubles take 2 slots assert(ix + 1 < cSlots); @@ -1197,13 +1232,14 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un } else { - printf("%s", getRegName(genMapRegArgNumToRegNum(regArgNum, argType))); + printf("%s", + getRegName(genMapRegArgNumToRegNum(regArgNum, argType, info.compCallConv))); } } else #endif // TARGET_ARM { - printf("%s", getRegName(genMapRegArgNumToRegNum(regArgNum, argType))); + printf("%s", getRegName(genMapRegArgNumToRegNum(regArgNum, argType, info.compCallConv))); } } } @@ -1372,7 +1408,8 @@ void Compiler::lvaInitGenericsCtxt(InitVarDscInfo* varDscInfo) /* Another register argument */ varDsc->lvIsRegArg = 1; - varDsc->SetArgReg(genMapRegArgNumToRegNum(varDscInfo->regArgNum(TYP_INT), varDsc->TypeGet())); + varDsc->SetArgReg( + genMapRegArgNumToRegNum(varDscInfo->regArgNum(TYP_INT), varDsc->TypeGet(), info.compCallConv)); #if FEATURE_MULTIREG_ARGS varDsc->SetOtherArgReg(REG_NA); #endif @@ -1439,7 +1476,7 @@ void Compiler::lvaInitVarArgsHandle(InitVarDscInfo* varDscInfo) unsigned varArgHndArgNum = varDscInfo->allocRegArg(TYP_I_IMPL); varDsc->lvIsRegArg = 1; - varDsc->SetArgReg(genMapRegArgNumToRegNum(varArgHndArgNum, TYP_I_IMPL)); + varDsc->SetArgReg(genMapRegArgNumToRegNum(varArgHndArgNum, TYP_I_IMPL, info.compCallConv)); #if FEATURE_MULTIREG_ARGS varDsc->SetOtherArgReg(REG_NA); #endif @@ -6699,10 +6736,10 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals() } #ifdef TARGET_ARM64 - if (info.compIsVarArgs && varDsc->GetArgReg() != theFixedRetBuffArgNum()) + if (info.compIsVarArgs && (varDsc->GetArgReg() != theFixedRetBuffReg(info.compCallConv))) { // Stack offset to varargs (parameters) should point to home area which will be preallocated. - const unsigned regArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg()); + const unsigned regArgNum = genMapIntRegNumToRegArgNum(varDsc->GetArgReg(), info.compCallConv); varDsc->SetStackOffset(-initialStkOffs + regArgNum * REGSIZE_BYTES); continue; } diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 0d4c8b9a26612c..0eba0d6b19bdc2 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -2133,7 +2133,7 @@ void LinearScan::UpdateRegStateForStructArg(LclVarDsc* argDsc) } else { - compiler->raCheckValidIntParamReg(argDsc, argDsc->GetArgReg()); + assert((genRegMask(argDsc->GetArgReg()) & fullIntArgRegMask(compiler->info.compCallConv)) != RBM_NONE); intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->GetArgReg()); } } @@ -2147,7 +2147,7 @@ void LinearScan::UpdateRegStateForStructArg(LclVarDsc* argDsc) } else { - compiler->raCheckValidIntParamReg(argDsc, argDsc->GetOtherArgReg()); + assert((genRegMask(argDsc->GetOtherArgReg()) & fullIntArgRegMask(compiler->info.compCallConv)) != RBM_NONE); intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->GetOtherArgReg()); } } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 8a58576f7f348d..646bfa76e771fa 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -2662,7 +2662,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call { assert(size == 1); size = 2; - nextOtherRegNum = genMapIntRegArgNumToRegNum(intArgRegNum); + nextOtherRegNum = genMapIntRegArgNumToRegNum(intArgRegNum, call->GetUnmanagedCallConv()); } } } @@ -2677,7 +2677,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call isRegArg = (intArgRegNum + (size - 1)) < maxRegArgs; if (!passUsingFloatRegs && isRegArg && (size > 1)) { - nextOtherRegNum = genMapIntRegArgNumToRegNum(intArgRegNum + 1); + nextOtherRegNum = genMapIntRegArgNumToRegNum(intArgRegNum + 1, call->GetUnmanagedCallConv()); } // Did we run out of registers when we had a 16-byte struct (size===2) ? @@ -2816,7 +2816,8 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call { if (structDesc.IsIntegralSlot(i)) { - *nextRegNumPtrs[i] = genMapIntRegArgNumToRegNum(intArgRegNum + structIntRegs); + *nextRegNumPtrs[i] = + genMapIntRegArgNumToRegNum(intArgRegNum + structIntRegs, call->GetUnmanagedCallConv()); ++structIntRegs; } else if (structDesc.IsSseSlot(i)) @@ -2830,8 +2831,9 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call else { // fill in or update the argInfo table - nextRegNum = passUsingFloatRegs ? genMapFloatRegArgNumToRegNum(nextFltArgRegNum) - : genMapIntRegArgNumToRegNum(intArgRegNum); + nextRegNum = passUsingFloatRegs + ? genMapFloatRegArgNumToRegNum(nextFltArgRegNum) + : genMapIntRegArgNumToRegNum(intArgRegNum, call->GetUnmanagedCallConv()); } #ifdef WINDOWS_AMD64_ABI diff --git a/src/coreclr/jit/regalloc.cpp b/src/coreclr/jit/regalloc.cpp index 5c44f2dbd95a4f..ea33ea50cf41fe 100644 --- a/src/coreclr/jit/regalloc.cpp +++ b/src/coreclr/jit/regalloc.cpp @@ -104,11 +104,11 @@ regNumber Compiler::raUpdateRegStateForArg(RegState* regState, LclVarDsc* argDsc if (regState->rsIsFloat) { - assert(inArgMask & RBM_FLTARG_REGS); + assert((inArgMask & RBM_FLTARG_REGS) != RBM_NONE); } else { - raCheckValidIntParamReg(argDsc, inArgReg); + assert((inArgMask & fullIntArgRegMask(info.compCallConv)) != RBM_NONE); } regState->rsCalleeRegArgMaskLiveIn |= inArgMask; @@ -169,42 +169,6 @@ regNumber Compiler::raUpdateRegStateForArg(RegState* regState, LclVarDsc* argDsc return inArgReg; } -//------------------------------------------------------------------------ -// raCheckValidIntParamReg: -// Check that an integer parameter's register information matches what we -// expect. -// -// Parameters: -// argDsc - LclVarDsc* for the parameter -// inArgReg - Register used by the parameter -// -void Compiler::raCheckValidIntParamReg(LclVarDsc* argDsc, regNumber inArgReg) -{ -#ifdef DEBUG - // This might be the fixed return buffer register argument (on ARM64) - // We check and allow inArgReg to be theFixedRetBuffReg - if (hasFixedRetBuffReg() && (inArgReg == theFixedRetBuffReg())) - { - // We should have a TYP_BYREF or TYP_I_IMPL arg and not a TYP_STRUCT arg - assert(argDsc->lvType == TYP_BYREF || argDsc->lvType == TYP_I_IMPL); - // We should have recorded the variable number for the return buffer arg - assert(info.compRetBuffArg != BAD_VAR_NUM); - } -#ifdef SWIFT_SUPPORT - else if ((info.compCallConv == CorInfoCallConvExtension::Swift) && (inArgReg == REG_SWIFT_SELF)) - { - assert((lvaSwiftSelfArg != BAD_VAR_NUM) && - ((argDsc == lvaGetDesc(lvaSwiftSelfArg)) || - (argDsc->lvIsStructField && argDsc->lvParentLcl == lvaSwiftSelfArg))); - } -#endif - else // we have a regular arg - { - assert((genRegMask(inArgReg) & RBM_ARG_REGS) != RBM_NONE); - } -#endif -} - //------------------------------------------------------------------------ // rpMustCreateEBPFrame: // Returns true when we must create an EBP frame diff --git a/src/coreclr/jit/regset.cpp b/src/coreclr/jit/regset.cpp index b87533c0e4e8f3..efec31a78f5bd5 100644 --- a/src/coreclr/jit/regset.cpp +++ b/src/coreclr/jit/regset.cpp @@ -895,7 +895,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX regNumber genRegArgNext(regNumber argReg) { - assert(isValidIntArgReg(argReg) || isValidFloatArgReg(argReg)); + assert(isValidIntArgReg(argReg, CorInfoCallConvExtension::Managed) || isValidFloatArgReg(argReg)); switch (argReg) { diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index 7897e0c7fc9323..94a4810c561238 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -419,10 +419,12 @@ inline bool genIsValidDoubleReg(regNumber reg) // hasFixedRetBuffReg: // Returns true if our target architecture uses a fixed return buffer register // -inline bool hasFixedRetBuffReg() +inline bool hasFixedRetBuffReg(CorInfoCallConvExtension callConv) { -#ifdef TARGET_ARM64 +#if defined(TARGET_ARM64) return true; +#elif defined(TARGET_AMD64) && defined(SWIFT_SUPPORT) + return callConv == CorInfoCallConvExtension::Swift; #else return false; #endif @@ -432,11 +434,14 @@ inline bool hasFixedRetBuffReg() // theFixedRetBuffReg: // Returns the regNumber to use for the fixed return buffer // -inline regNumber theFixedRetBuffReg() +inline regNumber theFixedRetBuffReg(CorInfoCallConvExtension callConv) { - assert(hasFixedRetBuffReg()); // This predicate should be checked before calling this method -#ifdef TARGET_ARM64 + assert(hasFixedRetBuffReg(callConv)); // This predicate should be checked before calling this method +#if defined(TARGET_ARM64) return REG_ARG_RET_BUFF; +#elif defined(TARGET_AMD64) && defined(SWIFT_SUPPORT) + assert(callConv == CorInfoCallConvExtension::Swift); + return REG_SWIFT_ARG_RET_BUFF; #else return REG_NA; #endif @@ -446,11 +451,14 @@ inline regNumber theFixedRetBuffReg() // theFixedRetBuffMask: // Returns the regNumber to use for the fixed return buffer // -inline regMaskTP theFixedRetBuffMask() +inline regMaskTP theFixedRetBuffMask(CorInfoCallConvExtension callConv) { - assert(hasFixedRetBuffReg()); // This predicate should be checked before calling this method -#ifdef TARGET_ARM64 + assert(hasFixedRetBuffReg(callConv)); // This predicate should be checked before calling this method +#if defined(TARGET_ARM64) return RBM_ARG_RET_BUFF; +#elif defined(TARGET_AMD64) && defined(SWIFT_SUPPORT) + assert(callConv == CorInfoCallConvExtension::Swift); + return RBM_SWIFT_ARG_RET_BUFF; #else return 0; #endif @@ -460,11 +468,14 @@ inline regMaskTP theFixedRetBuffMask() // theFixedRetBuffArgNum: // Returns the argNum to use for the fixed return buffer // -inline unsigned theFixedRetBuffArgNum() +inline unsigned theFixedRetBuffArgNum(CorInfoCallConvExtension callConv) { - assert(hasFixedRetBuffReg()); // This predicate should be checked before calling this method + assert(hasFixedRetBuffReg(callConv)); // This predicate should be checked before calling this method #ifdef TARGET_ARM64 return RET_BUFF_ARGNUM; +#elif defined(TARGET_AMD64) && defined(SWIFT_SUPPORT) + assert(callConv == CorInfoCallConvExtension::Swift); + return SWIFT_RET_BUFF_ARGNUM; #else return BAD_VAR_NUM; #endif @@ -475,16 +486,22 @@ inline unsigned theFixedRetBuffArgNum() // Returns the full mask of all possible integer registers // Note this includes the fixed return buffer register on Arm64 // -inline regMaskTP fullIntArgRegMask() +inline regMaskTP fullIntArgRegMask(CorInfoCallConvExtension callConv) { - if (hasFixedRetBuffReg()) + regMaskTP result = RBM_ARG_REGS; + if (hasFixedRetBuffReg(callConv)) { - return RBM_ARG_REGS | theFixedRetBuffMask(); + result |= theFixedRetBuffMask(callConv); } - else + +#ifdef SWIFT_SUPPORT + if (callConv == CorInfoCallConvExtension::Swift) { - return RBM_ARG_REGS; + result |= RBM_SWIFT_SELF; } +#endif + + return result; } //------------------------------------------------------------------------------------------- @@ -492,9 +509,9 @@ inline regMaskTP fullIntArgRegMask() // Returns true if the register is a valid integer argument register // Note this method also returns true on Arm64 when 'reg' is the RetBuff register // -inline bool isValidIntArgReg(regNumber reg) +inline bool isValidIntArgReg(regNumber reg, CorInfoCallConvExtension callConv) { - return (genRegMask(reg) & fullIntArgRegMask()) != 0; + return (genRegMask(reg) & fullIntArgRegMask(callConv)) != 0; } //------------------------------------------------------------------------------------------- diff --git a/src/coreclr/jit/targetamd64.h b/src/coreclr/jit/targetamd64.h index 8a349f5ab1aac6..a15029c3c39249 100644 --- a/src/coreclr/jit/targetamd64.h +++ b/src/coreclr/jit/targetamd64.h @@ -573,6 +573,8 @@ #define REG_SWIFT_INTRET_ORDER REG_RAX,REG_RDX,REG_RCX,REG_R8 #define REG_SWIFT_FLOATRET_ORDER REG_XMM0,REG_XMM1,REG_XMM2,REG_XMM3 #define REG_SWIFT_ARG_RET_BUFF REG_RAX + #define RBM_SWIFT_ARG_RET_BUFF RBM_RAX + #define SWIFT_RET_BUFF_ARGNUM MAX_REG_ARG #endif // clang-format on diff --git a/src/coreclr/vm/amd64/theprestubamd64.S b/src/coreclr/vm/amd64/theprestubamd64.S index dd02f70780e2f2..8d601c0ab9f280 100644 --- a/src/coreclr/vm/amd64/theprestubamd64.S +++ b/src/coreclr/vm/amd64/theprestubamd64.S @@ -6,7 +6,8 @@ #include "asmconstants.h" NESTED_ENTRY ThePreStub, _TEXT, NoHandler - PROLOG_WITH_TRANSITION_BLOCK 0, 0, 0, 0, 0 + PROLOG_WITH_TRANSITION_BLOCK 8, 0, 0, 0, 0 + mov [rsp], rax // Return buffer in Swift calling convention // // call PreStubWorker @@ -14,9 +15,11 @@ NESTED_ENTRY ThePreStub, _TEXT, NoHandler lea rdi, [rsp + __PWTB_TransitionBlock] // pTransitionBlock* mov rsi, METHODDESC_REGISTER call C_FUNC(PreStubWorker) + mov r10, rax + mov rax, [rsp] EPILOG_WITH_TRANSITION_BLOCK_TAILCALL - TAILJMP_RAX + jmp r10 NESTED_END ThePreStub, _TEXT diff --git a/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs b/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs index 8dc301f171006a..33e8dac7a184c0 100644 --- a/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs +++ b/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.cs @@ -14,12 +14,29 @@ public unsafe class SwiftCallbackAbiStress { private const string SwiftLib = "libSwiftCallbackAbiStress.dylib"; + [StructLayout(LayoutKind.Sequential, Size = 24)] + struct F0_Ret + { + public ushort F0; + public float F1; + public int F2; + public ulong F3; + + public F0_Ret(ushort f0, float f1, int f2, ulong f3) + { + F0 = f0; + F1 = f1; + F2 = f2; + F3 = f3; + } + } + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func01fs5UInt8VAEs5Int16V_s5Int32Vs6UInt64Vs6UInt16Vs5Int64VSds6UInt32VAMSiAKtXE_tF")] - private static extern byte SwiftCallbackFunc0(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func01fAA6F0_RetVAEs5Int16V_s5Int32Vs6UInt64Vs6UInt16Vs5Int64VSds6UInt32VAMSiAKtXE_tF")] + private static extern F0_Ret SwiftCallbackFunc0(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static byte SwiftCallbackFunc0Callback(short a0, int a1, ulong a2, ushort a3, long a4, double a5, uint a6, ushort a7, nint a8, ulong a9, SwiftSelf self) + private static F0_Ret SwiftCallbackFunc0Callback(short a0, int a1, ulong a2, ushort a3, long a4, double a5, uint a6, ushort a7, nint a8, ulong a9, SwiftSelf self) { try { @@ -39,7 +56,7 @@ private static byte SwiftCallbackFunc0Callback(short a0, int a1, ulong a2, ushor *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 254; + return new F0_Ret(65117, 981990, 1192391225, 7001579272668151908); } [Fact] @@ -47,34 +64,46 @@ public static void TestSwiftCallbackFunc0() { Console.Write("Running SwiftCallbackFunc0: "); ExceptionDispatchInfo ex = null; - byte val = SwiftCallbackFunc0(&SwiftCallbackFunc0Callback, &ex); + F0_Ret val = SwiftCallbackFunc0(&SwiftCallbackFunc0Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((byte)254, val); + Assert.Equal((ushort)65117, val.F0); + Assert.Equal((float)981990, val.F1); + Assert.Equal((int)1192391225, val.F2); + Assert.Equal((ulong)7001579272668151908, val.F3); Console.WriteLine("OK"); } [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func11fS2ds4Int8V_s5Int16VSfs5Int64VtXE_tF")] - private static extern double SwiftCallbackFunc1(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func11fS2uSd_s4Int8Vs5Int32Vs6UInt16Vs5UInt8VSdAKs6UInt64Vs5Int16VS2fAmEtXE_tF")] + private static extern nuint SwiftCallbackFunc1(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static double SwiftCallbackFunc1Callback(sbyte a0, short a1, float a2, long a3, SwiftSelf self) + private static nuint SwiftCallbackFunc1Callback(double a0, sbyte a1, int a2, ushort a3, byte a4, double a5, byte a6, ulong a7, short a8, float a9, float a10, ulong a11, sbyte a12, SwiftSelf self) { try { - Assert.Equal((sbyte)-117, a0); - Assert.Equal((short)24667, a1); - Assert.Equal((float)7203656, a2); - Assert.Equal((long)2859275717293113701, a3); + Assert.Equal((double)3867437130564654, a0); + Assert.Equal((sbyte)-64, a1); + Assert.Equal((int)31081182, a2); + Assert.Equal((ushort)20316, a3); + Assert.Equal((byte)73, a4); + Assert.Equal((double)3543740592144911, a5); + Assert.Equal((byte)250, a6); + Assert.Equal((ulong)6680393408153342744, a7); + Assert.Equal((short)23758, a8); + Assert.Equal((float)7189013, a9); + Assert.Equal((float)5438196, a10); + Assert.Equal((ulong)3310322731568932038, a11); + Assert.Equal((sbyte)3, a12); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 1815003852073252; + return unchecked((nuint)2172476334497055933); } [Fact] @@ -82,44 +111,58 @@ public static void TestSwiftCallbackFunc1() { Console.Write("Running SwiftCallbackFunc1: "); ExceptionDispatchInfo ex = null; - double val = SwiftCallbackFunc1(&SwiftCallbackFunc1Callback, &ex); + nuint val = SwiftCallbackFunc1(&SwiftCallbackFunc1Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((double)1815003852073252, val); + Assert.Equal((nuint)unchecked((nuint)2172476334497055933), val); Console.WriteLine("OK"); } + [StructLayout(LayoutKind.Sequential, Size = 12)] + struct F2_Ret_S0 + { + public long F0; + public int F1; + + public F2_Ret_S0(long f0, int f1) + { + F0 = f0; + F1 = f1; + } + } + + [StructLayout(LayoutKind.Sequential, Size = 14)] + struct F2_Ret + { + public F2_Ret_S0 F0; + public short F1; + + public F2_Ret(F2_Ret_S0 f0, short f1) + { + F0 = f0; + F1 = f1; + } + } + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func21fs5UInt8VAEs4Int8V_s6UInt32VSfSuAegIs6UInt64Vs5Int64Vs5Int16Vs5Int32VAOSiSutXE_tF")] - private static extern byte SwiftCallbackFunc2(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func21fAA6F2_RetVAESu_s5UInt8VtXE_tF")] + private static extern F2_Ret SwiftCallbackFunc2(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static byte SwiftCallbackFunc2Callback(sbyte a0, uint a1, float a2, nuint a3, byte a4, sbyte a5, uint a6, ulong a7, long a8, short a9, int a10, short a11, nint a12, nuint a13, SwiftSelf self) + private static F2_Ret SwiftCallbackFunc2Callback(nuint a0, byte a1, SwiftSelf self) { try { - Assert.Equal((sbyte)93, a0); - Assert.Equal((uint)571731946, a1); - Assert.Equal((float)1958727, a2); - Assert.Equal((nuint)unchecked((nuint)3919017851053326963), a3); - Assert.Equal((byte)156, a4); - Assert.Equal((sbyte)-17, a5); - Assert.Equal((uint)747962023, a6); - Assert.Equal((ulong)1104840539654964163, a7); - Assert.Equal((long)5642679323997486487, a8); - Assert.Equal((short)29557, a9); - Assert.Equal((int)660273506, a10); - Assert.Equal((short)-14877, a11); - Assert.Equal((nint)unchecked((nint)3546952189496193868), a12); - Assert.Equal((nuint)unchecked((nuint)3599444831393612282), a13); + Assert.Equal((nuint)unchecked((nuint)2153637757371267722), a0); + Assert.Equal((byte)150, a1); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 141; + return new F2_Ret(new F2_Ret_S0(5628852360797741825, 939232542), -9943); } [Fact] @@ -127,54 +170,70 @@ public static void TestSwiftCallbackFunc2() { Console.Write("Running SwiftCallbackFunc2: "); ExceptionDispatchInfo ex = null; - byte val = SwiftCallbackFunc2(&SwiftCallbackFunc2Callback, &ex); + F2_Ret val = SwiftCallbackFunc2(&SwiftCallbackFunc2Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((byte)141, val); + Assert.Equal((long)5628852360797741825, val.F0.F0); + Assert.Equal((int)939232542, val.F0.F1); + Assert.Equal((short)-9943, val.F1); Console.WriteLine("OK"); } + [StructLayout(LayoutKind.Sequential, Size = 10)] + struct F3_Ret_S0 + { + public short F0; + public int F1; + public ushort F2; + + public F3_Ret_S0(short f0, int f1, ushort f2) + { + F0 = f0; + F1 = f1; + F2 = f2; + } + } + + [StructLayout(LayoutKind.Sequential, Size = 33)] + struct F3_Ret + { + public nint F0; + public F3_Ret_S0 F1; + public nuint F2; + public sbyte F3; + + public F3_Ret(nint f0, F3_Ret_S0 f1, nuint f2, sbyte f3) + { + F0 = f0; + F1 = f1; + F2 = f2; + F3 = f3; + } + } + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func31fS2dSi_s5UInt8Vs4Int8Vs5Int64VAGs6UInt16VS2uSiSfAKs6UInt32VSiAEs5Int16Vs5Int32VAKSuAgESdSiAmGtXE_tF")] - private static extern double SwiftCallbackFunc3(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func31fAA6F3_RetVAEs6UInt16V_S2uSiSfAGtXE_tF")] + private static extern F3_Ret SwiftCallbackFunc3(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static double SwiftCallbackFunc3Callback(nint a0, byte a1, sbyte a2, long a3, sbyte a4, ushort a5, nuint a6, nuint a7, nint a8, float a9, ushort a10, uint a11, nint a12, byte a13, short a14, int a15, ushort a16, nuint a17, sbyte a18, byte a19, double a20, nint a21, uint a22, sbyte a23, SwiftSelf self) + private static F3_Ret SwiftCallbackFunc3Callback(ushort a0, nuint a1, nuint a2, nint a3, float a4, ushort a5, SwiftSelf self) { try { - Assert.Equal((nint)unchecked((nint)5610153900386943274), a0); - Assert.Equal((byte)236, a1); - Assert.Equal((sbyte)-6, a2); - Assert.Equal((long)3316874161259890183, a3); - Assert.Equal((sbyte)-53, a4); - Assert.Equal((ushort)37580, a5); - Assert.Equal((nuint)unchecked((nuint)1683057726956349710), a6); - Assert.Equal((nuint)unchecked((nuint)415152378126297632), a7); - Assert.Equal((nint)unchecked((nint)2870393941738319551), a8); - Assert.Equal((float)1652893, a9); - Assert.Equal((ushort)16825, a10); - Assert.Equal((uint)419224712, a11); - Assert.Equal((nint)unchecked((nint)7680849977572141563), a12); - Assert.Equal((byte)200, a13); - Assert.Equal((short)22892, a14); - Assert.Equal((int)2118994921, a15); - Assert.Equal((ushort)44276, a16); - Assert.Equal((nuint)unchecked((nuint)4006990310546323213), a17); - Assert.Equal((sbyte)-39, a18); - Assert.Equal((byte)67, a19); - Assert.Equal((double)3008014901411425, a20); - Assert.Equal((nint)unchecked((nint)7039812168807528075), a21); - Assert.Equal((uint)1057070707, a22); - Assert.Equal((sbyte)103, a23); + Assert.Equal((ushort)45065, a0); + Assert.Equal((nuint)unchecked((nuint)8506742096411295359), a1); + Assert.Equal((nuint)unchecked((nuint)8619375465417625458), a2); + Assert.Equal((nint)unchecked((nint)5288917394772427257), a3); + Assert.Equal((float)5678138, a4); + Assert.Equal((ushort)33467, a5); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 171601370856717; + return new F3_Ret(unchecked((nint)3330016214205716187), new F3_Ret_S0(-29819, 2075852318, 671), unchecked((nuint)2368015527878194540), -79); } [Fact] @@ -182,54 +241,72 @@ public static void TestSwiftCallbackFunc3() { Console.Write("Running SwiftCallbackFunc3: "); ExceptionDispatchInfo ex = null; - double val = SwiftCallbackFunc3(&SwiftCallbackFunc3Callback, &ex); + F3_Ret val = SwiftCallbackFunc3(&SwiftCallbackFunc3Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((double)171601370856717, val); + Assert.Equal((nint)unchecked((nint)3330016214205716187), val.F0); + Assert.Equal((short)-29819, val.F1.F0); + Assert.Equal((int)2075852318, val.F1.F1); + Assert.Equal((ushort)671, val.F1.F2); + Assert.Equal((nuint)unchecked((nuint)2368015527878194540), val.F2); + Assert.Equal((sbyte)-79, val.F3); Console.WriteLine("OK"); } + [StructLayout(LayoutKind.Sequential, Size = 24)] + struct F4_Ret + { + public ulong F0; + public uint F1; + public ulong F2; + + public F4_Ret(ulong f0, uint f1, ulong f2) + { + F0 = f0; + F1 = f1; + F2 = f2; + } + } + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func41fs5Int64VAEs6UInt16V_Sfs5Int32VAGs4Int8VSfs6UInt64Vs5Int16VSdA2kISiAi2eiMs6UInt32VAMs5UInt8VAISuAKtXE_tF")] - private static extern long SwiftCallbackFunc4(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func41fAA6F4_RetVAEs5Int64V_s6UInt16Vs5Int32VAISiSdAISfAkIs4Int8VSfs6UInt64Vs5Int16VSdA2mKSiAk2GtXE_tF")] + private static extern F4_Ret SwiftCallbackFunc4(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static long SwiftCallbackFunc4Callback(ushort a0, float a1, int a2, ushort a3, sbyte a4, float a5, ulong a6, short a7, double a8, sbyte a9, sbyte a10, int a11, nint a12, int a13, long a14, long a15, int a16, ulong a17, uint a18, ulong a19, byte a20, int a21, nuint a22, sbyte a23, SwiftSelf self) + private static F4_Ret SwiftCallbackFunc4Callback(long a0, ushort a1, int a2, ushort a3, nint a4, double a5, ushort a6, float a7, int a8, ushort a9, sbyte a10, float a11, ulong a12, short a13, double a14, sbyte a15, sbyte a16, int a17, nint a18, int a19, long a20, long a21, SwiftSelf self) { try { - Assert.Equal((ushort)64787, a0); - Assert.Equal((float)1472942, a1); - Assert.Equal((int)2042281537, a2); - Assert.Equal((ushort)18667, a3); - Assert.Equal((sbyte)-102, a4); - Assert.Equal((float)1768897, a5); - Assert.Equal((ulong)8888237425788084647, a6); - Assert.Equal((short)20853, a7); - Assert.Equal((double)3454973030441503, a8); - Assert.Equal((sbyte)-46, a9); - Assert.Equal((sbyte)-63, a10); - Assert.Equal((int)366699691, a11); - Assert.Equal((nint)unchecked((nint)4641984012938514811), a12); - Assert.Equal((int)1691113876, a13); - Assert.Equal((long)6912906265890433291, a14); - Assert.Equal((long)6701017449244003958, a15); - Assert.Equal((int)568887433, a16); - Assert.Equal((ulong)9099941242643212987, a17); - Assert.Equal((uint)1380054056, a18); - Assert.Equal((ulong)595836183051442276, a19); - Assert.Equal((byte)174, a20); - Assert.Equal((int)1047364523, a21); - Assert.Equal((nuint)unchecked((nuint)1417646176372805029), a22); - Assert.Equal((sbyte)-35, a23); + Assert.Equal((long)8771527078890676837, a0); + Assert.Equal((ushort)18667, a1); + Assert.Equal((int)224631333, a2); + Assert.Equal((ushort)13819, a3); + Assert.Equal((nint)unchecked((nint)8888237425788084647), a4); + Assert.Equal((double)2677321682649925, a5); + Assert.Equal((ushort)50276, a6); + Assert.Equal((float)2703201, a7); + Assert.Equal((int)545337834, a8); + Assert.Equal((ushort)11190, a9); + Assert.Equal((sbyte)112, a10); + Assert.Equal((float)4053251, a11); + Assert.Equal((ulong)7107857019164433129, a12); + Assert.Equal((short)-3092, a13); + Assert.Equal((double)2176685406663423, a14); + Assert.Equal((sbyte)57, a15); + Assert.Equal((sbyte)-61, a16); + Assert.Equal((int)866840318, a17); + Assert.Equal((nint)unchecked((nint)5927291145767969522), a18); + Assert.Equal((int)1818333546, a19); + Assert.Equal((long)6272248211765159948, a20); + Assert.Equal((long)6555966806846053216, a21); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 3100893724073759448; + return new F4_Ret(2182947204061522719, 1721424472, 7504841280611598884); } [Fact] @@ -237,45 +314,70 @@ public static void TestSwiftCallbackFunc4() { Console.Write("Running SwiftCallbackFunc4: "); ExceptionDispatchInfo ex = null; - long val = SwiftCallbackFunc4(&SwiftCallbackFunc4Callback, &ex); + F4_Ret val = SwiftCallbackFunc4(&SwiftCallbackFunc4Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((long)3100893724073759448, val); + Assert.Equal((ulong)2182947204061522719, val.F0); + Assert.Equal((uint)1721424472, val.F1); + Assert.Equal((ulong)7504841280611598884, val.F2); Console.WriteLine("OK"); } + [StructLayout(LayoutKind.Sequential, Size = 40)] + struct F5_Ret + { + public ulong F0; + public int F1; + public nint F2; + public float F3; + public short F4; + public ulong F5; + + public F5_Ret(ulong f0, int f1, nint f2, float f3, short f4, ulong f5) + { + F0 = f0; + F1 = f1; + F2 = f2; + F3 = f3; + F4 = f4; + F5 = f5; + } + } + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func51fS2is4Int8V_s5UInt8VSis6UInt64VAIs5Int64Vs5Int16VAmKs6UInt16VAgOSfAIs5Int32VtXE_tF")] - private static extern nint SwiftCallbackFunc5(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func51fAA6F5_RetVAEs5Int32V_s6UInt16VAIs5Int16Vs5UInt8Vs4Int8VAMSis6UInt64VAQs5Int64VA2ksimItXE_tF")] + private static extern F5_Ret SwiftCallbackFunc5(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static nint SwiftCallbackFunc5Callback(sbyte a0, byte a1, nint a2, ulong a3, ulong a4, long a5, short a6, short a7, long a8, ushort a9, byte a10, ushort a11, float a12, ulong a13, int a14, SwiftSelf self) + private static F5_Ret SwiftCallbackFunc5Callback(int a0, ushort a1, ushort a2, short a3, byte a4, sbyte a5, byte a6, nint a7, ulong a8, ulong a9, long a10, short a11, short a12, long a13, ushort a14, byte a15, ushort a16, SwiftSelf self) { try { - Assert.Equal((sbyte)-86, a0); - Assert.Equal((byte)201, a1); - Assert.Equal((nint)unchecked((nint)3436765034579128495), a2); - Assert.Equal((ulong)6305137336506323506, a3); - Assert.Equal((ulong)6280137078630028944, a4); - Assert.Equal((long)6252650621827449809, a5); - Assert.Equal((short)306, a6); - Assert.Equal((short)-27739, a7); - Assert.Equal((long)8386588676727568762, a8); - Assert.Equal((ushort)24144, a9); - Assert.Equal((byte)230, a10); - Assert.Equal((ushort)59907, a11); - Assert.Equal((float)1791462, a12); - Assert.Equal((ulong)8271399067416599310, a13); - Assert.Equal((int)1699875267, a14); + Assert.Equal((int)359602150, a0); + Assert.Equal((ushort)51495, a1); + Assert.Equal((ushort)37765, a2); + Assert.Equal((short)29410, a3); + Assert.Equal((byte)95, a4); + Assert.Equal((sbyte)-104, a5); + Assert.Equal((byte)32, a6); + Assert.Equal((nint)unchecked((nint)8530952551906271255), a7); + Assert.Equal((ulong)706266487837805024, a8); + Assert.Equal((ulong)707905209555595641, a9); + Assert.Equal((long)8386588676727568762, a10); + Assert.Equal((short)-8624, a11); + Assert.Equal((short)26113, a12); + Assert.Equal((long)8389143657021522019, a13); + Assert.Equal((ushort)13337, a14); + Assert.Equal((byte)229, a15); + Assert.Equal((ushort)51876, a16); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return unchecked((nint)5224035852455624489); + return new F5_Ret(5224035852455624489, 493616651, unchecked((nint)3355493231962241213), 8151117, -6001, 2418751914358801711); } [Fact] @@ -283,48 +385,49 @@ public static void TestSwiftCallbackFunc5() { Console.Write("Running SwiftCallbackFunc5: "); ExceptionDispatchInfo ex = null; - nint val = SwiftCallbackFunc5(&SwiftCallbackFunc5Callback, &ex); + F5_Ret val = SwiftCallbackFunc5(&SwiftCallbackFunc5Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((nint)unchecked((nint)5224035852455624489), val); + Assert.Equal((ulong)5224035852455624489, val.F0); + Assert.Equal((int)493616651, val.F1); + Assert.Equal((nint)unchecked((nint)3355493231962241213), val.F2); + Assert.Equal((float)8151117, val.F3); + Assert.Equal((short)-6001, val.F4); + Assert.Equal((ulong)2418751914358801711, val.F5); Console.WriteLine("OK"); } [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func61fs5Int64VAEs6UInt32V_Sfs5UInt8Vs5Int32VAGs6UInt64VAKs4Int8VS2is5Int16VSiAg2meGs6UInt16VtXE_tF")] - private static extern long SwiftCallbackFunc6(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func61fs6UInt16VAEs5Int32V_s6UInt32Vs6UInt64VAGs4Int8VS2is5Int16VSiAi2Ks5Int64VAItXE_tF")] + private static extern ushort SwiftCallbackFunc6(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static long SwiftCallbackFunc6Callback(uint a0, float a1, byte a2, int a3, uint a4, ulong a5, int a6, sbyte a7, nint a8, nint a9, short a10, nint a11, uint a12, ulong a13, ulong a14, long a15, uint a16, ushort a17, SwiftSelf self) + private static ushort SwiftCallbackFunc6Callback(int a0, uint a1, ulong a2, int a3, sbyte a4, nint a5, nint a6, short a7, nint a8, uint a9, ulong a10, ulong a11, long a12, uint a13, SwiftSelf self) { try { - Assert.Equal((uint)743741783, a0); - Assert.Equal((float)3321238, a1); - Assert.Equal((byte)51, a2); - Assert.Equal((int)1315779092, a3); - Assert.Equal((uint)1375736443, a4); - Assert.Equal((ulong)7022244764256789748, a5); - Assert.Equal((int)156967479, a6); - Assert.Equal((sbyte)-120, a7); - Assert.Equal((nint)unchecked((nint)3560129042279209151), a8); - Assert.Equal((nint)unchecked((nint)9064213378356024089), a9); - Assert.Equal((short)7947, a10); - Assert.Equal((nint)unchecked((nint)8756231901741598476), a11); - Assert.Equal((uint)56423704, a12); - Assert.Equal((ulong)6962175160124965670, a13); - Assert.Equal((ulong)2935089705514798822, a14); - Assert.Equal((long)1348139258363155351, a15); - Assert.Equal((uint)1754662893, a16); - Assert.Equal((ushort)35528, a17); + Assert.Equal((int)743741783, a0); + Assert.Equal((uint)850236948, a1); + Assert.Equal((ulong)5908745692727636656, a2); + Assert.Equal((int)2106839818, a3); + Assert.Equal((sbyte)77, a4); + Assert.Equal((nint)unchecked((nint)291907785975160065), a5); + Assert.Equal((nint)unchecked((nint)3560129042279209151), a6); + Assert.Equal((short)-30568, a7); + Assert.Equal((nint)unchecked((nint)5730241035812482149), a8); + Assert.Equal((uint)18625011, a9); + Assert.Equal((ulong)242340713355417257, a10); + Assert.Equal((ulong)6962175160124965670, a11); + Assert.Equal((long)2935089705514798822, a12); + Assert.Equal((uint)2051956645, a13); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 2428870998079250366; + return 45160; } [Fact] @@ -332,50 +435,64 @@ public static void TestSwiftCallbackFunc6() { Console.Write("Running SwiftCallbackFunc6: "); ExceptionDispatchInfo ex = null; - long val = SwiftCallbackFunc6(&SwiftCallbackFunc6Callback, &ex); + ushort val = SwiftCallbackFunc6(&SwiftCallbackFunc6Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((long)2428870998079250366, val); + Assert.Equal((ushort)45160, val); Console.WriteLine("OK"); } + [StructLayout(LayoutKind.Sequential, Size = 8)] + struct F7_Ret_S0 + { + public nint F0; + + public F7_Ret_S0(nint f0) + { + F0 = f0; + } + } + + [StructLayout(LayoutKind.Sequential, Size = 20)] + struct F7_Ret + { + public sbyte F0; + public sbyte F1; + public byte F2; + public F7_Ret_S0 F3; + public uint F4; + + public F7_Ret(sbyte f0, sbyte f1, byte f2, F7_Ret_S0 f3, uint f4) + { + F0 = f0; + F1 = f1; + F2 = f2; + F3 = f3; + F4 = f4; + } + } + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func71fS2is5UInt8V_s5Int16VSus6UInt32Vs4Int8VAkESfSiAiESfs5Int64VSdAKSiAgMS2dtXE_tF")] - private static extern nint SwiftCallbackFunc7(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func71fAA6F7_RetVAEs6UInt64V_s5UInt8Vs5Int16VSutXE_tF")] + private static extern F7_Ret SwiftCallbackFunc7(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static nint SwiftCallbackFunc7Callback(byte a0, short a1, nuint a2, uint a3, sbyte a4, sbyte a5, byte a6, float a7, nint a8, uint a9, byte a10, float a11, long a12, double a13, sbyte a14, nint a15, short a16, long a17, double a18, double a19, SwiftSelf self) + private static F7_Ret SwiftCallbackFunc7Callback(ulong a0, byte a1, short a2, nuint a3, SwiftSelf self) { try { - Assert.Equal((byte)134, a0); - Assert.Equal((short)-32369, a1); - Assert.Equal((nuint)unchecked((nuint)8380717554783122608), a2); - Assert.Equal((uint)1860099027, a3); - Assert.Equal((sbyte)-6, a4); - Assert.Equal((sbyte)86, a5); - Assert.Equal((byte)32, a6); - Assert.Equal((float)1160734, a7); - Assert.Equal((nint)unchecked((nint)6413974004534568863), a8); - Assert.Equal((uint)835905835, a9); - Assert.Equal((byte)1, a10); - Assert.Equal((float)7455267, a11); - Assert.Equal((long)6652417171359975799, a12); - Assert.Equal((double)3767979765576223, a13); - Assert.Equal((sbyte)-92, a14); - Assert.Equal((nint)unchecked((nint)2188807859088864320), a15); - Assert.Equal((short)22602, a16); - Assert.Equal((long)6695605905030342661, a17); - Assert.Equal((double)3516012226643358, a18); - Assert.Equal((double)1125481383704537, a19); + Assert.Equal((ulong)7625368278886567558, a0); + Assert.Equal((byte)70, a1); + Assert.Equal((short)26780, a2); + Assert.Equal((nuint)unchecked((nuint)7739343395912136630), a3); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return unchecked((nint)4420963390330795075); + return new F7_Ret(-96, -93, 251, new F7_Ret_S0(unchecked((nint)3590193056511262571)), 13223810); } [Fact] @@ -383,43 +500,36 @@ public static void TestSwiftCallbackFunc7() { Console.Write("Running SwiftCallbackFunc7: "); ExceptionDispatchInfo ex = null; - nint val = SwiftCallbackFunc7(&SwiftCallbackFunc7Callback, &ex); + F7_Ret val = SwiftCallbackFunc7(&SwiftCallbackFunc7Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((nint)unchecked((nint)4420963390330795075), val); + Assert.Equal((sbyte)-96, val.F0); + Assert.Equal((sbyte)-93, val.F1); + Assert.Equal((byte)251, val.F2); + Assert.Equal((nint)unchecked((nint)3590193056511262571), val.F3.F0); + Assert.Equal((uint)13223810, val.F4); Console.WriteLine("OK"); } [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func81fs4Int8VAESd_Sds6UInt64Vs6UInt16VSds6UInt32VAiEs5UInt8Vs5Int16VAGSfAItXE_tF")] - private static extern sbyte SwiftCallbackFunc8(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func81fs5UInt8VAESf_SutXE_tF")] + private static extern byte SwiftCallbackFunc8(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static sbyte SwiftCallbackFunc8Callback(double a0, double a1, ulong a2, ushort a3, double a4, uint a5, ushort a6, sbyte a7, byte a8, short a9, ulong a10, float a11, ushort a12, SwiftSelf self) + private static byte SwiftCallbackFunc8Callback(float a0, nuint a1, SwiftSelf self) { try { - Assert.Equal((double)378554201505534, a0); - Assert.Equal((double)1650526878176435, a1); - Assert.Equal((ulong)7125767448027274022, a2); - Assert.Equal((ushort)19812, a3); - Assert.Equal((double)1173178493312463, a4); - Assert.Equal((uint)416842395, a5); - Assert.Equal((ushort)46360, a6); - Assert.Equal((sbyte)-60, a7); - Assert.Equal((byte)107, a8); - Assert.Equal((short)-2849, a9); - Assert.Equal((ulong)3245727696885859461, a10); - Assert.Equal((float)3340085, a11); - Assert.Equal((ushort)24776, a12); + Assert.Equal((float)6278007, a0); + Assert.Equal((nuint)unchecked((nuint)1620979945874429615), a1); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 30; + return 60; } [Fact] @@ -427,46 +537,72 @@ public static void TestSwiftCallbackFunc8() { Console.Write("Running SwiftCallbackFunc8: "); ExceptionDispatchInfo ex = null; - sbyte val = SwiftCallbackFunc8(&SwiftCallbackFunc8Callback, &ex); + byte val = SwiftCallbackFunc8(&SwiftCallbackFunc8Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((sbyte)30, val); + Assert.Equal((byte)60, val); Console.WriteLine("OK"); } + [StructLayout(LayoutKind.Sequential, Size = 26)] + struct F9_Ret + { + public uint F0; + public long F1; + public ulong F2; + public ushort F3; + + public F9_Ret(uint f0, long f1, ulong f2, ushort f3) + { + F0 = f0; + F1 = f1; + F2 = f2; + F3 = f3; + } + } + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] - [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func91fS2ds5Int16V_SiAEs5UInt8Vs6UInt32Vs5Int64Vs6UInt64Vs6UInt16VAOs4Int8VAkgqKSfAQtXE_tF")] - private static extern double SwiftCallbackFunc9(delegate* unmanaged[Swift] func, void* funcContext); + [DllImport(SwiftLib, EntryPoint = "$s22SwiftCallbackAbiStress05swiftB5Func91fAA6F9_RetVAEs4Int8V_Sis5Int16Vs5Int64VS2dSis6UInt16VAMS2fAMs6UInt32VAIs5Int32VAQs6UInt64VAiKSis5UInt8VAmISiAItXE_tF")] + private static extern F9_Ret SwiftCallbackFunc9(delegate* unmanaged[Swift] func, void* funcContext); [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSwift) })] - private static double SwiftCallbackFunc9Callback(short a0, nint a1, short a2, byte a3, uint a4, long a5, ulong a6, ushort a7, ushort a8, sbyte a9, long a10, byte a11, sbyte a12, long a13, float a14, sbyte a15, SwiftSelf self) + private static F9_Ret SwiftCallbackFunc9Callback(sbyte a0, nint a1, short a2, long a3, double a4, double a5, nint a6, ushort a7, ushort a8, float a9, float a10, ushort a11, uint a12, short a13, int a14, int a15, ulong a16, short a17, long a18, nint a19, byte a20, ushort a21, short a22, nint a23, short a24, SwiftSelf self) { try { - Assert.Equal((short)4555, a0); + Assert.Equal((sbyte)17, a0); Assert.Equal((nint)unchecked((nint)4720638462358523954), a1); Assert.Equal((short)30631, a2); - Assert.Equal((byte)123, a3); - Assert.Equal((uint)2112687301, a4); - Assert.Equal((long)1804058604961822948, a5); - Assert.Equal((ulong)8772179036715198777, a6); - Assert.Equal((ushort)54948, a7); - Assert.Equal((ushort)29928, a8); - Assert.Equal((sbyte)-36, a9); - Assert.Equal((long)7573525757641791389, a10); - Assert.Equal((byte)239, a11); - Assert.Equal((sbyte)-71, a12); - Assert.Equal((long)7143939705627605769, a13); - Assert.Equal((float)2647713, a14); - Assert.Equal((sbyte)-7, a15); + Assert.Equal((long)8206569929240962953, a3); + Assert.Equal((double)1359667226908383, a4); + Assert.Equal((double)3776001892555053, a5); + Assert.Equal((nint)unchecked((nint)747160900180286726), a6); + Assert.Equal((ushort)12700, a7); + Assert.Equal((ushort)53813, a8); + Assert.Equal((float)7860389, a9); + Assert.Equal((float)1879743, a10); + Assert.Equal((ushort)61400, a11); + Assert.Equal((uint)1962814337, a12); + Assert.Equal((short)17992, a13); + Assert.Equal((int)677814589, a14); + Assert.Equal((int)1019483263, a15); + Assert.Equal((ulong)6326265259403184370, a16); + Assert.Equal((short)-14633, a17); + Assert.Equal((long)4127072498763789519, a18); + Assert.Equal((nint)unchecked((nint)4008108205305320386), a19); + Assert.Equal((byte)128, a20); + Assert.Equal((ushort)21189, a21); + Assert.Equal((short)32104, a22); + Assert.Equal((nint)unchecked((nint)384827814282870543), a23); + Assert.Equal((short)20647, a24); } catch (Exception ex) { *(ExceptionDispatchInfo*)self.Value = ExceptionDispatchInfo.Capture(ex); } - return 3088996708692961; + return new F9_Ret(189282789, 114803850982111219, 4506415416389763390, 23584); } [Fact] @@ -474,11 +610,14 @@ public static void TestSwiftCallbackFunc9() { Console.Write("Running SwiftCallbackFunc9: "); ExceptionDispatchInfo ex = null; - double val = SwiftCallbackFunc9(&SwiftCallbackFunc9Callback, &ex); + F9_Ret val = SwiftCallbackFunc9(&SwiftCallbackFunc9Callback, &ex); if (ex != null) ex.Throw(); - Assert.Equal((double)3088996708692961, val); + Assert.Equal((uint)189282789, val.F0); + Assert.Equal((long)114803850982111219, val.F1); + Assert.Equal((ulong)4506415416389763390, val.F2); + Assert.Equal((ushort)23584, val.F3); Console.WriteLine("OK"); } diff --git a/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.swift b/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.swift index aeb63ee8c72864..344fd65a5ed2a3 100644 --- a/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.swift +++ b/src/tests/Interop/Swift/SwiftCallbackAbiStress/SwiftCallbackAbiStress.swift @@ -3,43 +3,127 @@ import Foundation -public func swiftCallbackFunc0(f: (Int16, Int32, UInt64, UInt16, Int64, Double, UInt32, UInt16, Int, UInt64) -> UInt8) -> UInt8 { +@frozen +public struct F0_Ret +{ + public let f0 : UInt16; + public let f1 : Float; + public let f2 : Int32; + public let f3 : UInt64; +} + +public func swiftCallbackFunc0(f: (Int16, Int32, UInt64, UInt16, Int64, Double, UInt32, UInt16, Int, UInt64) -> F0_Ret) -> F0_Ret { return f(-17813, 318006528, 1195162122024233590, 60467, 4587464142261794085, 2686980744237725, 331986645, 56299, 6785053689615432643, 6358078381523084952) } -public func swiftCallbackFunc1(f: (Int8, Int16, Float, Int64) -> Double) -> Double { - return f(-117, 24667, 7203656, 2859275717293113701) +public func swiftCallbackFunc1(f: (Double, Int8, Int32, UInt16, UInt8, Double, UInt8, UInt64, Int16, Float, Float, UInt64, Int8) -> UInt) -> UInt { + return f(3867437130564654, -64, 31081182, 20316, 73, 3543740592144911, 250, 6680393408153342744, 23758, 7189013, 5438196, 3310322731568932038, 3) +} + +@frozen +public struct F2_Ret_S0 +{ + public let f0 : Int64; + public let f1 : Int32; +} + +@frozen +public struct F2_Ret +{ + public let f0 : F2_Ret_S0; + public let f1 : Int16; +} + +public func swiftCallbackFunc2(f: (UInt, UInt8) -> F2_Ret) -> F2_Ret { + return f(2153637757371267722, 150) +} + +@frozen +public struct F3_Ret_S0 +{ + public let f0 : Int16; + public let f1 : Int32; + public let f2 : UInt16; +} + +@frozen +public struct F3_Ret +{ + public let f0 : Int; + public let f1 : F3_Ret_S0; + public let f2 : UInt; + public let f3 : Int8; +} + +public func swiftCallbackFunc3(f: (UInt16, UInt, UInt, Int, Float, UInt16) -> F3_Ret) -> F3_Ret { + return f(45065, 8506742096411295359, 8619375465417625458, 5288917394772427257, 5678138, 33467) +} + +@frozen +public struct F4_Ret +{ + public let f0 : UInt64; + public let f1 : UInt32; + public let f2 : UInt64; +} + +public func swiftCallbackFunc4(f: (Int64, UInt16, Int32, UInt16, Int, Double, UInt16, Float, Int32, UInt16, Int8, Float, UInt64, Int16, Double, Int8, Int8, Int32, Int, Int32, Int64, Int64) -> F4_Ret) -> F4_Ret { + return f(8771527078890676837, 18667, 224631333, 13819, 8888237425788084647, 2677321682649925, 50276, 2703201, 545337834, 11190, 112, 4053251, 7107857019164433129, -3092, 2176685406663423, 57, -61, 866840318, 5927291145767969522, 1818333546, 6272248211765159948, 6555966806846053216) +} + +@frozen +public struct F5_Ret +{ + public let f0 : UInt64; + public let f1 : Int32; + public let f2 : Int; + public let f3 : Float; + public let f4 : Int16; + public let f5 : UInt64; } -public func swiftCallbackFunc2(f: (Int8, UInt32, Float, UInt, UInt8, Int8, UInt32, UInt64, Int64, Int16, Int32, Int16, Int, UInt) -> UInt8) -> UInt8 { - return f(93, 571731946, 1958727, 3919017851053326963, 156, -17, 747962023, 1104840539654964163, 5642679323997486487, 29557, 660273506, -14877, 3546952189496193868, 3599444831393612282) +public func swiftCallbackFunc5(f: (Int32, UInt16, UInt16, Int16, UInt8, Int8, UInt8, Int, UInt64, UInt64, Int64, Int16, Int16, Int64, UInt16, UInt8, UInt16) -> F5_Ret) -> F5_Ret { + return f(359602150, 51495, 37765, 29410, 95, -104, 32, 8530952551906271255, 706266487837805024, 707905209555595641, 8386588676727568762, -8624, 26113, 8389143657021522019, 13337, 229, 51876) } -public func swiftCallbackFunc3(f: (Int, UInt8, Int8, Int64, Int8, UInt16, UInt, UInt, Int, Float, UInt16, UInt32, Int, UInt8, Int16, Int32, UInt16, UInt, Int8, UInt8, Double, Int, UInt32, Int8) -> Double) -> Double { - return f(5610153900386943274, 236, -6, 3316874161259890183, -53, 37580, 1683057726956349710, 415152378126297632, 2870393941738319551, 1652893, 16825, 419224712, 7680849977572141563, 200, 22892, 2118994921, 44276, 4006990310546323213, -39, 67, 3008014901411425, 7039812168807528075, 1057070707, 103) +public func swiftCallbackFunc6(f: (Int32, UInt32, UInt64, Int32, Int8, Int, Int, Int16, Int, UInt32, UInt64, UInt64, Int64, UInt32) -> UInt16) -> UInt16 { + return f(743741783, 850236948, 5908745692727636656, 2106839818, 77, 291907785975160065, 3560129042279209151, -30568, 5730241035812482149, 18625011, 242340713355417257, 6962175160124965670, 2935089705514798822, 2051956645) } -public func swiftCallbackFunc4(f: (UInt16, Float, Int32, UInt16, Int8, Float, UInt64, Int16, Double, Int8, Int8, Int32, Int, Int32, Int64, Int64, Int32, UInt64, UInt32, UInt64, UInt8, Int32, UInt, Int8) -> Int64) -> Int64 { - return f(64787, 1472942, 2042281537, 18667, -102, 1768897, 8888237425788084647, 20853, 3454973030441503, -46, -63, 366699691, 4641984012938514811, 1691113876, 6912906265890433291, 6701017449244003958, 568887433, 9099941242643212987, 1380054056, 595836183051442276, 174, 1047364523, 1417646176372805029, -35) +@frozen +public struct F7_Ret_S0 +{ + public let f0 : Int; } -public func swiftCallbackFunc5(f: (Int8, UInt8, Int, UInt64, UInt64, Int64, Int16, Int16, Int64, UInt16, UInt8, UInt16, Float, UInt64, Int32) -> Int) -> Int { - return f(-86, 201, 3436765034579128495, 6305137336506323506, 6280137078630028944, 6252650621827449809, 306, -27739, 8386588676727568762, 24144, 230, 59907, 1791462, 8271399067416599310, 1699875267) +@frozen +public struct F7_Ret +{ + public let f0 : Int8; + public let f1 : Int8; + public let f2 : UInt8; + public let f3 : F7_Ret_S0; + public let f4 : UInt32; } -public func swiftCallbackFunc6(f: (UInt32, Float, UInt8, Int32, UInt32, UInt64, Int32, Int8, Int, Int, Int16, Int, UInt32, UInt64, UInt64, Int64, UInt32, UInt16) -> Int64) -> Int64 { - return f(743741783, 3321238, 51, 1315779092, 1375736443, 7022244764256789748, 156967479, -120, 3560129042279209151, 9064213378356024089, 7947, 8756231901741598476, 56423704, 6962175160124965670, 2935089705514798822, 1348139258363155351, 1754662893, 35528) +public func swiftCallbackFunc7(f: (UInt64, UInt8, Int16, UInt) -> F7_Ret) -> F7_Ret { + return f(7625368278886567558, 70, 26780, 7739343395912136630) } -public func swiftCallbackFunc7(f: (UInt8, Int16, UInt, UInt32, Int8, Int8, UInt8, Float, Int, UInt32, UInt8, Float, Int64, Double, Int8, Int, Int16, Int64, Double, Double) -> Int) -> Int { - return f(134, -32369, 8380717554783122608, 1860099027, -6, 86, 32, 1160734, 6413974004534568863, 835905835, 1, 7455267, 6652417171359975799, 3767979765576223, -92, 2188807859088864320, 22602, 6695605905030342661, 3516012226643358, 1125481383704537) +public func swiftCallbackFunc8(f: (Float, UInt) -> UInt8) -> UInt8 { + return f(6278007, 1620979945874429615) } -public func swiftCallbackFunc8(f: (Double, Double, UInt64, UInt16, Double, UInt32, UInt16, Int8, UInt8, Int16, UInt64, Float, UInt16) -> Int8) -> Int8 { - return f(378554201505534, 1650526878176435, 7125767448027274022, 19812, 1173178493312463, 416842395, 46360, -60, 107, -2849, 3245727696885859461, 3340085, 24776) +@frozen +public struct F9_Ret +{ + public let f0 : UInt32; + public let f1 : Int64; + public let f2 : UInt64; + public let f3 : UInt16; } -public func swiftCallbackFunc9(f: (Int16, Int, Int16, UInt8, UInt32, Int64, UInt64, UInt16, UInt16, Int8, Int64, UInt8, Int8, Int64, Float, Int8) -> Double) -> Double { - return f(4555, 4720638462358523954, 30631, 123, 2112687301, 1804058604961822948, 8772179036715198777, 54948, 29928, -36, 7573525757641791389, 239, -71, 7143939705627605769, 2647713, -7) +public func swiftCallbackFunc9(f: (Int8, Int, Int16, Int64, Double, Double, Int, UInt16, UInt16, Float, Float, UInt16, UInt32, Int16, Int32, Int32, UInt64, Int16, Int64, Int, UInt8, UInt16, Int16, Int, Int16) -> F9_Ret) -> F9_Ret { + return f(17, 4720638462358523954, 30631, 8206569929240962953, 1359667226908383, 3776001892555053, 747160900180286726, 12700, 53813, 7860389, 1879743, 61400, 1962814337, 17992, 677814589, 1019483263, 6326265259403184370, -14633, 4127072498763789519, 4008108205305320386, 128, 21189, 32104, 384827814282870543, 20647) }