[musl] Re: ppc64le and 32-bit LE userland compatibility

Daniel Kolesa daniel@octaforge.org
Fri Jun 5 02:18:18 GMT 2020


On Fri, Jun 5, 2020, at 01:35, Segher Boessenkool wrote:
> Hi!
> 
> On Thu, Jun 04, 2020 at 11:43:53PM +0200, Daniel Kolesa wrote:
> > The thing is, I've yet to see in which way the ELFv2 ABI *actually* requires VSX - I don't think compiling for 970 introduces any actual differences. There will be omissions, yes - but then the more accurate thing would be to say that a subset of ELFv2 is used, rather than it being a different ABI per se.
> 
> Two big things are that binaries that someone else made are supposed to
> work for you as well -- including binaries using VSX registers, or any
> instructions that require ISA 2.07 (or some older ISA after 970).  This
> includes DSOs (shared libraries).  So for a distribution this means that
> they will not use VSX *anywhere*, or only in very specialised things.
> That is a many-years setback, for people/situations where it could be
> used.

Third party precompiled stuff doesn't really need to concern us, since none really exists. It's also still an upgrade over ELFv1 regardless (I mean, the same things apply there). I'm also not really all that convinced that vectors make a huge difference in non-specialized code (autovectorization still has a way to go) and code written to use vector instructions should probably check auxval and take those paths at runtime. As for other instructions, fair enough, but from my rough testing, it doesn't make such a massive difference for average case (and where it does, one can always rebuild their thing with CFLAGS=-mcpu=power9)

> 
> > The ELFv2 document specifies things like passing of quadruple precision floats. Indeed, VSX is needed there, but that's not a concern if you *don't* use quadruple precision floats.
> 
> As Joseph says, QP float is passed in the VRs, so that works just fine
> *if* you have AltiVec.  If not, you probably should pass such values in
> the GPRs, or however a struct of 16 bytes is passed in whatever ABI you
> use (this is a much more general problem than just BE ELFv2 ;-) )  And
> then you have some kind of "partial soft float".  Fun!  (Or not...)

As I mentioned previously, I kinda want to be able to cover the same targets as ELFv1 can, which also means non-altivec hardware, so it doesn't matter that much either way... being able to cover existing stable compilers with a manageable patchset would be nice, too.

> 
> > > If you always use -mcpu=970 (or similar), then not very much is
> > > different for you most likely -- except of course there is no promise
> > > to the user that they can use VSX and all instructions in ISA 2.07,
> > > which is a very useful promise to have normally.
> > 
> > Yes, -mcpu=970 is used for default packages. *However*, it is possible that the user compiles their own packages with -mcpu=power9 or something similar, and then it'll be possible to utilize VSX and all, and it should still work with the existing userland. When speaking of ABI, what matters is... well, the binary interface, which is the same - so I believe this is still ELFv2. A subset is always compliant with the whole.
> 
> The same calling convention will probably work, yes.  An ABI is more
> than that though.
> 
> 
> > > Btw, if you use GCC, *please* send in testresults?  :-)
> > 
> > Yes, it's all gcc (we do have clang, but compiling repo packages with clang is generally frowned upon in the project, as we have vast majority of packages cross-compilable, and our cross-compiling infrastructure is gcc-centric, plus we enable certain things by default such as hardening flags that clang does not support). I'll try to remember next time I'm running tests.
> 
> Thanks in advance!
> 
> > I have a feeling that glibc would object to such port, since it means it would have to exist in parallel with a potential different ELFv2 port that does have a POWER8 minimal requirement; gcc would need a way to tell them apart, too (based on what would they be told apart? the simplest way would probably be something like, if --with-abi=elfv2 { if --with-cpu < power8 -> use glibc-novsx else use glibc-vsx } ...)
> 
> The target name allows to make such distinctions: this could for example
> be  powerpc64-*-linux-void  (maybe I put the distinction in the wrong
> part of the name here?  The glibc people will know better, and "void" is
> probably not a great name anyway).

Hm, I'm not a huge fan of putting ABI specifics in the triplet, it feels wrong - there is no precedent for it with POWER (ARM did it with EABI though), the last part should remain 'gnu' as it's still glibc; besides, gcc is compiled for exactly one target triplet, and traditionally with ppc compilers it's always been possible to target everything with just one compiler (endian, 32bit, 64bit, abi...). Detection based on CPU is probably quirky too, actually, since it'd mean different CPU types selecting different dynamic linkers.

The best way would probably be adding a new -mabi, e.g. -mabi=elfv2-novsx (just an example), which would behave exactly like -mabi=elfv2, except it'd emit some extra detection macro - that would be documented in the ABI spec (and glibc could use it to choose the correct port), allow gcc (or clang) to select a correct dynamic linker name, and probably default to a 64-bit long double format. This would also get rid of the patches used for musl which pick the default -mlong-double based on target triples :) Alternatively, since -mabi is additive, it could be a modifier for -mabi=elfv2, which would perhaps make even more sense. Clang would need similar changes. I think this way would respect existing conventions the most and be overall least invasive.

Thoughts?

> 
> 
> Segher
>

Daniel


More information about the Libc-alpha mailing list