[swift-dev] Returning more than two scalars from C code

John McCall rjmccall at apple.com
Wed Mar 30 14:45:15 CDT 2016


> On Mar 30, 2016, at 12:09 PM, Bryan Chan <bryan.chan at ca.ibm.com> wrote:
> 
> Thanks for your responses so far. It took me a while to fully appreciate
> what all this means.
> 
> I have read through John's mail thread on llvm-dev about adding the swiftcc
> convention to LLVM/Clang. I don't think that discussion mentioned adding
> Clang support for C++ functions returning aggregates in multiple registers
> for targets that currently use sret, because, in John's words, "we don't
> use the Swift CC to call C functions." But aren't these runtime functions
> using TwoWordPair::Return doing exactly that?

One of the reasons to implement a swiftcall CC attribute in Clang is precisely
so that we can make the C declaration request the use of the Swift CC directly.

> On i386 and ARM, the TwoWordPair::Return type is masqueraded as a 64-bit
> unsigned long long so that the returned values are passed in a register
> pair. This trick is not portable, and infeasible on at least s390x.

You will need to implement the Swift CC for your target.

> A portable solution would be to implement such runtime functions in Swift,
> and make them retrieve the needed results from two calls to C++, instead
> of one call to a C++ function that returns a pair. The Swift function
> can then return value pairs as usual. This seems much cleaner and simpler.

We're not going to implement every single runtime function in Swift.

John.

> 
> Bryan
> 
> 
> rjmccall at apple.com wrote on 2016-03-22 03:51:52 PM:
> 
> > On Mar 22, 2016, at 12:25 PM, Joe Groff <jgroff at apple.com> wrote:
> > > On Mar 22, 2016, at 12:06 PM, Bryan Chan <bryan.chan at ca.ibm.com> wrote:
> > > 
> > > > jgroff at apple.com wrote on 2016-03-22 02:37:47 PM:
> > > > 
> > > > > The runtime functions are hacked in various unsavory ways to give 
> > > > > them Swift-like calling conventions. Many of them also have 
> > > > > important semantics that the compiler needs to be aware of, so if 
> > > > > they aren't exported as standard library API in some way, you really
> > > > > shouldn't interact with them directly. 
> > > > > (swift_class_getInstanceExtents happens to be OK, but what are you 
> > > > > trying to do with it?)
> > > > 
> > > > I am trying to build Swift on a different architecture (s390x). This
> > > > function was causing crashes due to the ABI mismatch, and I also
> > > > found that the issue is not 100% fixed on x86 either, so I wondered
> > > > if the community has an opinion on the right way to deal with this
> > > > in the runtime, or if the answer is simply "don't do this for
> > > > 3-scalar returns".
> > >
> > > Yeah, there's no good way right now to return three scalars from 
> > > Clang. swift_class_getInstanceExtents and a few other runtime 
> > > entrypoints like allocBox and allocError use the 
> > > `TwoWordPair::Return` hack to use types that happen to return in two
> > > registers on i386, x86_64, armv7, and arm64. If s390x's C ABI 
> > > doesn't define any such types, you might need to wait for proper 
> > > support for Swift calling conventions in Clang. I believe it's on 
> > > John McCall's near-term todo list to do that.
> > 
> > To be clear, you'll still need to implement the swiftcc convention 
> > for your target in LLVM/clang, so it will still take some compiler 
> > implementation expertise to get right.  But at least the 
> > compatibility assumptions will be explicit.



More information about the swift-dev mailing list