@@ -1817,6 +1817,15 @@ regNumber CallArgs::GetCustomRegister(Compiler* comp, CorInfoCallConvExtension c
18171817 }
18181818 }
18191819
1820+ #if defined(TARGET_AMD64) && defined(SWIFT_SUPPORT)
1821+ // TODO-Cleanup: Unify this with hasFixedRetBuffReg. That will
1822+ // likely be necessary for the reverse pinvoke support regardless.
1823+ if (cc == CorInfoCallConvExtension::Swift)
1824+ {
1825+ return REG_SWIFT_ARG_RET_BUFF;
1826+ }
1827+ #endif
1828+
18201829 break;
18211830
18221831 case WellKnownArg::VirtualStubCell:
@@ -26856,6 +26865,14 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp,
2685626865 {
2685726866 assert(varTypeIsStruct(returnType));
2685826867
26868+ #ifdef SWIFT_SUPPORT
26869+ if (callConv == CorInfoCallConvExtension::Swift)
26870+ {
26871+ InitializeSwiftReturnRegs(comp, retClsHnd);
26872+ break;
26873+ }
26874+ #endif
26875+
2685926876#ifdef UNIX_AMD64_ABI
2686026877
2686126878 SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
@@ -26959,6 +26976,31 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp,
2695926976#endif
2696026977}
2696126978
26979+ #ifdef SWIFT_SUPPORT
26980+ //---------------------------------------------------------------------------------------
26981+ // InitializeSwiftReturnRegs:
26982+ // Initialize the Return Type Descriptor for a method that returns with the
26983+ // Swift calling convention.
26984+ //
26985+ // Parameters:
26986+ // comp - Compiler instance
26987+ // clsHnd - Struct type being returned
26988+ //
26989+ void ReturnTypeDesc::InitializeSwiftReturnRegs(Compiler* comp, CORINFO_CLASS_HANDLE clsHnd)
26990+ {
26991+ const CORINFO_SWIFT_LOWERING* lowering = comp->GetSwiftLowering(clsHnd);
26992+ assert(!lowering->byReference);
26993+
26994+ static_assert_no_msg(MAX_SWIFT_LOWERED_ELEMENTS <= MAX_RET_REG_COUNT);
26995+ assert(lowering->numLoweredElements <= MAX_RET_REG_COUNT);
26996+
26997+ for (size_t i = 0; i < lowering->numLoweredElements; i++)
26998+ {
26999+ m_regType[i] = JITtype2varType(lowering->loweredElements[i]);
27000+ }
27001+ }
27002+ #endif
27003+
2696227004//---------------------------------------------------------------------------------------
2696327005// InitializeLongReturnType:
2696427006// Initialize the Return Type Descriptor for a method that returns a TYP_LONG
@@ -27022,8 +27064,9 @@ void ReturnTypeDesc::InitializeReturnType(Compiler* comp,
2702227064// GetABIReturnReg: Return i'th return register as per target ABI
2702327065//
2702427066// Arguments:
27025- // idx - Index of the return register.
27026- // The first return register has an index of 0 and so on.
27067+ // idx - Index of the return register.
27068+ // The first return register has an index of 0 and so on.
27069+ // callConv - Associated calling convention
2702727070//
2702827071// Return Value:
2702927072// Returns i'th return register as per target ABI.
@@ -27032,13 +27075,44 @@ void ReturnTypeDesc::InitializeReturnType(Compiler* comp,
2703227075// x86 and ARM return long in multiple registers.
2703327076// ARM and ARM64 return HFA struct in multiple registers.
2703427077//
27035- regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) const
27078+ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx, CorInfoCallConvExtension callConv ) const
2703627079{
2703727080 unsigned count = GetReturnRegCount();
2703827081 assert(idx < count);
2703927082
2704027083 regNumber resultReg = REG_NA;
2704127084
27085+ #ifdef SWIFT_SUPPORT
27086+ if (callConv == CorInfoCallConvExtension::Swift)
27087+ {
27088+ static const regNumber swiftIntReturnRegs[] = {REG_SWIFT_INTRET_ORDER};
27089+ static const regNumber swiftFloatReturnRegs[] = {REG_SWIFT_FLOATRET_ORDER};
27090+ assert((idx < ArrLen(swiftIntReturnRegs)) && (idx < ArrLen(swiftFloatReturnRegs)));
27091+ unsigned intRegIdx = 0;
27092+ unsigned floatRegIdx = 0;
27093+ for (unsigned i = 0; i < idx; i++)
27094+ {
27095+ if (varTypeUsesIntReg(GetReturnRegType(i)))
27096+ {
27097+ intRegIdx++;
27098+ }
27099+ else
27100+ {
27101+ floatRegIdx++;
27102+ }
27103+ }
27104+
27105+ if (varTypeUsesIntReg(GetReturnRegType(idx)))
27106+ {
27107+ return swiftIntReturnRegs[intRegIdx];
27108+ }
27109+ else
27110+ {
27111+ return swiftFloatReturnRegs[floatRegIdx];
27112+ }
27113+ }
27114+ #endif
27115+
2704227116#ifdef UNIX_AMD64_ABI
2704327117 var_types regType0 = GetReturnRegType(0);
2704427118
@@ -27186,7 +27260,7 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) const
2718627260// GetABIReturnRegs: get the mask of return registers as per target arch ABI.
2718727261//
2718827262// Arguments:
27189- // None
27263+ // callConv - The calling convention
2719027264//
2719127265// Return Value:
2719227266// reg mask of return registers in which the return type is returned.
@@ -27196,14 +27270,14 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx) const
2719627270// of return registers and wants to know the set of return registers.
2719727271//
2719827272// static
27199- regMaskTP ReturnTypeDesc::GetABIReturnRegs() const
27273+ regMaskTP ReturnTypeDesc::GetABIReturnRegs(CorInfoCallConvExtension callConv ) const
2720027274{
2720127275 regMaskTP resultMask = RBM_NONE;
2720227276
2720327277 unsigned count = GetReturnRegCount();
2720427278 for (unsigned i = 0; i < count; ++i)
2720527279 {
27206- resultMask |= genRegMask(GetABIReturnReg(i));
27280+ resultMask |= genRegMask(GetABIReturnReg(i, callConv ));
2720727281 }
2720827282
2720927283 return resultMask;
0 commit comments