mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Markus Wichmann <nullplan@gmx.net>
To: musl@lists.openwall.com
Subject: Re: [musl] [PATCH v2] add qsort_r.
Date: Tue, 9 Mar 2021 17:54:04 +0100	[thread overview]
Message-ID: <20210309165404.GB2766@voyager> (raw)
In-Reply-To: <20210309150320.GU32655@brightrain.aerifal.cx>

On Tue, Mar 09, 2021 at 10:03:22AM -0500, Rich Felker wrote:
> On Tue, Mar 09, 2021 at 05:13:39PM +0300, Alexander Monakov wrote:
> > Second, if you make a "conventional" wrapper, then on popular architectures
> > it is a single instruction (powerpc64 ABI demonstrates its insanity here):
> >
> > static int wrapper_cmp(void *v1, void *v2, void *ctx)
> > {
> > 	return ((cmpfun)ctx)(v1, v2);
> > }
> >
> > Some examples:
> >
> > amd64:	jmp %rdx
> > i386:	jmp *12(%esp)
> > arm:	bx r2
> > aarch64:br x2
> >
> > How is this not obvious?
>
> [...]
>
> For some reason though it's gigantic on powerpc64. It fails to do a
> tail call at all...
>

So, I experimented a bit with clang (for simplicity, since clang can
switch targets with a compiler switch). And indeed the above is
reproducible. Had to search around a bit for the ELFv2 ABI switch for
clang (the ELFv1 version is even worse, since it uses function
descriptors, so calling through a function pointer requires reading out
the function descriptors before being able to use them).

So with ELFv2, the function consists of buildup and teardown of a stack
frame, save and restore of R2, and the actual indirect call. The stack
frame is necessary because of R2 being spilled, and R2 being spilled is
necessary since the wrapper function might be called locally (so the
contract is that R2 is preserved), but the function pointer might point
to a function in another module, so R2 would be overwritten by the call.

That makes sense. What doesn't make sense is that the stack frame is
still used in 32-bit powerpc. Nothing is saved into that stack frame;
"mtctr 5; bctr" would be a valid implementation. But no matter what
switches I threw at it, the stack frame remained.

For other architectures: I could not test microblaze, mipsn32, m68k,
or1k, riscv64, and sh, since clang did not recognize those
architectures. Probably not included by default. MIPS and MIPS64 both
establish a stack frame, and s390x does not.

Ciao,
Markus

  reply	other threads:[~2021-03-09 16:54 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-09  3:56 Érico Nogueira
2021-03-09  9:11 ` Alexander Monakov
2021-03-09 13:42   ` Rich Felker
2021-03-09 14:13     ` Alexander Monakov
2021-03-09 15:03       ` Rich Felker
2021-03-09 16:54         ` Markus Wichmann [this message]
2021-03-09 18:04           ` Rich Felker
2021-03-15 23:49             ` Alexander Monakov
2021-03-16  2:18               ` Rich Felker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210309165404.GB2766@voyager \
    --to=nullplan@gmx.net \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).