Re: Calling conventions (particularly 32-bit ARM)

Liste des GroupesRevenir à c arch 
Sujet : Re: Calling conventions (particularly 32-bit ARM)
De : david.brown (at) *nospam* hesbynett.no (David Brown)
Groupes : comp.arch
Date : 07. Jan 2025, 09:49:16
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vlipqd$243c5$2@dont-email.me>
References : 1 2
User-Agent : Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0
On 06/01/2025 16:32, Anton Ertl wrote:
David Brown <david.brown@hesbynett.no> writes:
But the ABI only allows returning a single 32-bit value in R0, or a
scalar 64-bit value in R0:R1.  If a function returns a non-scalar that
is larger than 32-bit, the caller has to allocate space on the stack for
the return type and pass a pointer to that space in R0.
>
To my mind, this is massively inefficient, especially when using structs
that are made up of two 32-bit parts.
>
Is there any good reason why the ABI is designed with such limited
register usage for returns?
 Most calling conventions on RISCs are oriented towards C (if you want
calling conventions that try to be more cross-language (and slower),
look at VAX) and its properties and limitations at the time when the
calling convention was designed, in particular, the PCC
implementation, which was the de-facto standard Unix C compiler at the
time.  C compilers in the 1980s did not allocate structs to registers,
so passing structs in registers was foreign to them, so the solution
is that the caller passes the target struct as an additional
parameter.
 And passing the return value in registers might not have saved
anything on a compiler that does not deal with structs in registers.
Agreed.
This is all as I suspected - but it's nice to have it confirmed by others.

Struct returns were (and AFAIK still are, many decades after
they were added to C) a relatively rarely used feature, so Johnson
(PCC's author) probably did not want to waste a lot of effort on
making it more efficient.
 
I use struct returns sometimes in my C code, but they are (naturally enough) a far smaller proportion of return types than in C++ code.

gcc has an option -freg-struct-return, which does what you want.  Of
course, if you use this option on ARM A32/T32, you are not following
the calling convention, so you should only use it when all sides of a
struct return are compiled with that option.
 
I know about the -freg-struct-return option (and the requirements for using it), but it only has effect for 32-bit x86 as far as I know.  It certainly makes no difference for 32-bit ARM/Thumb.  (clang specifically says it does not support that option for 32-bit ARM/Thumb.)  I think part of this is that the calling convention already returns structs in registers - just as long as the struct fits in the single 32-bit register.

Newer ABIs like RISC-V 32-bit and x86_64
can at least use two registers for return values.  Modern compilers are
quite happy breaking structs into parts in individual registers - it's a
/long/ time since they insisted that structs occupied a contiguous block
of memory.
 ARM A32 is from 1985, and its calling convention is probably not much
younger.
 
I first used ARM assembly in the late 1980's, but that was mixed BBC BASIC and assembly, all with almost no documentation, so I don't know what calling conventions there were at that time.  (But the Acorn Archimedes was /really/ cool :-) )

I also think code would be a bit more efficient if there more registers
available for parameter passing and as scratch registers - perhaps 6
would make more sense.
 There is a tendency towards passing more parameters in registers in
more recent calling conventions.  IA-32 (and IIRC VAX) passes none,
MIPS uses 4 integer registers (for either integer or FP parameters),
Alpha uses 6 integer and 6 FP registers, AMD64's System V ABI 6
integer and 8 FP registers, ARM A64 has 8 integer and 8 FP registers,
RISC-V has 8 integer and 8 FP registers.  Not sure why they were so
reluctant to use more registers earlier.
 
Passing all parameters on the stack and returning a single int in a register was a perfect fit for old-style C where functions were often used without declarations.  It would certainly be a lot easier for variadic functions.  But once you start passing some parameters in registers, it seems strange to use so few.  Perhaps it was to make life easier for earlier compiler writers?  Things like lifetime analysis and register allocation algorithms were not as sophisticated as they are now - it used to be that if a variable used a register (via the C "register" qualifier), the register was dedicated to the variable throughout the function.  Too many registers for parameter passing might have left too few registers for function implementation, or at least made the compiler more complex.

In more modern C++ programming, it's very practical to use types like
std::optional<>, std::variant<>, std::expected<> and std::tuple<> as a
way of dealing safely with status and multiple return values rather than
using C-style error codes or passing manual pointers to return value
slots.
 The ARM calling convention is certainly much older than "modern C++
programming".
 
Yes.

But the limited return registers adds significant overhead to
small functions.
 C++ programmers think they know what C programming is about (and
unfortunately they dominate not just C++ compiler writers, but they
also damage C compilers while they are at it), so my sympathy for your
problem is very limited.
 
I program in C and C++, and in the past did a lot of assembly (mostly on 8-bit or 16-bit microcontrollers).  I am fully aware that C and C++ are different languages, and I write code in different styles for each.
For this issue, improving the calling convention would make the biggest difference for C++, but would also be a positive benefit for C.

Date Sujet#  Auteur
6 Jan 25 * Calling conventions (particularly 32-bit ARM)81David Brown
6 Jan 25 +* Re: Calling conventions (particularly 32-bit ARM)2Theo
7 Jan 25 i`- Re: Calling conventions (particularly 32-bit ARM)1David Brown
6 Jan 25 +* Re: Calling conventions (particularly 32-bit ARM)8Anton Ertl
6 Jan 25 i+* Re: Calling conventions (particularly 32-bit ARM)6MitchAlsup1
7 Jan 25 ii`* Re: Calling conventions (particularly 32-bit ARM)5David Brown
8 Jan 25 ii `* Re: Calling conventions (particularly 32-bit ARM)4MitchAlsup1
8 Jan 25 ii  +* Re: Calling conventions (particularly 32-bit ARM)2Chris M. Thomasson
8 Jan 25 ii  i`- Re: Calling conventions (particularly 32-bit ARM)1Chris M. Thomasson
8 Jan 25 ii  `- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
7 Jan 25 i`- Re: Calling conventions (particularly 32-bit ARM)1David Brown
6 Jan 25 `* Re: Calling conventions (particularly 32-bit ARM)70MitchAlsup1
7 Jan 25  +* Re: Calling conventions (particularly 32-bit ARM)18Waldek Hebisch
7 Jan 25  i+- Re: Calling conventions (particularly 32-bit ARM)1Lawrence D'Oliveiro
12 Jan 25  i`* Re: Calling conventions (particularly 32-bit ARM)16Stephen Fuld
12 Jan 25  i +- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
13 Jan 25  i +* Re: Calling conventions (particularly 32-bit ARM)11Waldek Hebisch
14 Jan 25  i i`* Re: Calling conventions (particularly 32-bit ARM)10Stephen Fuld
14 Jan 25  i i `* Re: Calling conventions (particularly 32-bit ARM)9Terje Mathisen
14 Jan 25  i i  `* Re: Calling conventions (particularly 32-bit ARM)8Michael S
15 Jan 25  i i   `* Re: Calling conventions (particularly 32-bit ARM)7MitchAlsup1
15 Jan 25  i i    +* Re: Calling conventions (particularly 32-bit ARM)3John Levine
15 Jan 25  i i    i`* Re: Calling conventions (particularly 32-bit ARM)2MitchAlsup1
15 Jan 25  i i    i `- Re: Calling conventions (particularly 32-bit ARM)1John Levine
16 Jan 25  i i    `* Re: Calling conventions (particularly 32-bit ARM)3Waldek Hebisch
16 Jan 25  i i     `* Re: Calling conventions (particularly 32-bit ARM)2MitchAlsup1
16 Jan 25  i i      `- Re: Calling conventions (particularly 32-bit ARM)1Waldek Hebisch
13 Jan 25  i `* Re: Calling conventions (particularly 32-bit ARM)3Thomas Koenig
14 Jan 25  i  `* Re: Calling conventions (particularly 32-bit ARM)2Thomas Koenig
14 Jan 25  i   `- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
7 Jan 25  +* Re: Calling conventions (particularly 32-bit ARM)6George Neuner
8 Jan 25  i+* Re: Calling conventions (particularly 32-bit ARM)3Stefan Monnier
9 Jan 25  ii`* Re: Calling conventions (particularly 32-bit ARM)2Anton Ertl
13 Jan 25  ii `- Re: Calling conventions (particularly 32-bit ARM)1Stefan Monnier
28 Jan 25  i`* Re: Calling conventions (particularly 32-bit ARM)2Tim Rentsch
29 Jan 25  i `- Re: Calling conventions (particularly 32-bit ARM)1George Neuner
8 Jan 25  `* Re: Calling conventions (particularly 32-bit ARM)45Stefan Monnier
8 Jan 25   +- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
8 Jan 25   `* Re: Calling conventions (particularly 32-bit ARM)43Anton Ertl
9 Jan 25    `* Re: Calling conventions (particularly 32-bit ARM)42Stefan Monnier
9 Jan 25     +- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
9 Jan 25     `* Re: Calling conventions (particularly 32-bit ARM)40Anton Ertl
9 Jan 25      +* Re: Calling conventions (particularly 32-bit ARM)2Thomas Koenig
10 Jan 25      i`- Re: Calling conventions (particularly 32-bit ARM)1Anton Ertl
9 Jan 25      +* Re: Calling conventions (particularly 32-bit ARM)4MitchAlsup1
9 Jan 25      i`* Re: Calling conventions (particularly 32-bit ARM)3Thomas Koenig
10 Jan 25      i `* Re: Calling conventions (particularly 32-bit ARM)2MitchAlsup1
10 Jan 25      i  `- Re: Calling conventions (particularly 32-bit ARM)1Thomas Koenig
10 Jan 25      +* Re: Calling conventions (particularly 32-bit ARM)29Waldek Hebisch
10 Jan 25      i`* Re: Calling conventions (particularly 32-bit ARM)28Anton Ertl
10 Jan 25      i +- Re: Calling conventions (particularly 32-bit ARM)1John Levine
13 Jan 25      i `* Re: Calling conventions (particularly 32-bit ARM)26MitchAlsup1
13 Jan 25      i  `* Re: Calling conventions (particularly 32-bit ARM)25Thomas Koenig
13 Jan 25      i   `* Re: Calling conventions (particularly 32-bit ARM)24MitchAlsup1
13 Jan 25      i    +* Re: Calling conventions (particularly 32-bit ARM)22MitchAlsup1
14 Jan 25      i    i+* Re: Calling conventions (particularly 32-bit ARM)17MitchAlsup1
14 Jan 25      i    ii+- Re: Calling conventions (particularly 32-bit ARM)1David Brown
14 Jan 25      i    ii+* Re: Calling conventions (particularly 32-bit ARM)2Michael S
14 Jan 25      i    iii`- Re: Calling conventions (particularly 32-bit ARM)1Anton Ertl
14 Jan 25      i    ii+- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
14 Jan 25      i    ii`* Re: Calling conventions (particularly 32-bit ARM)12Thomas Koenig
14 Jan 25      i    ii +* Re: Calling conventions (particularly 32-bit ARM)7Terje Mathisen
14 Jan 25      i    ii i+- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
14 Jan 25      i    ii i+* Re: Calling conventions (particularly 32-bit ARM)4Thomas Koenig
15 Jan 25      i    ii ii`* Re: Calling conventions (particularly 32-bit ARM)3Keith Thompson
15 Jan 25      i    ii ii +- Re: Calling conventions (particularly 32-bit ARM)1Keith Thompson
15 Jan 25      i    ii ii `- Re: Calling conventions (particularly 32-bit ARM)1Keith Thompson
14 Jan 25      i    ii i`- Re: Calling conventions (particularly 32-bit ARM)1Michael S
14 Jan 25      i    ii +- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
14 Jan 25      i    ii `* Re: Calling conventions (particularly 32-bit ARM)3Thomas Koenig
14 Jan 25      i    ii  `* Re: Calling conventions (particularly 32-bit ARM)2Michael S
15 Jan 25      i    ii   `- Re: Calling conventions (particularly 32-bit ARM)1MitchAlsup1
14 Jan 25      i    i+- Re: Calling conventions (particularly 32-bit ARM)1Thomas Koenig
14 Jan 25      i    i`* Re: Calling conventions (particularly 32-bit ARM)3David Brown
14 Jan 25      i    i `* Re: Calling conventions (particularly 32-bit ARM)2David Brown
15 Jan 25      i    i  `- Re: Calling conventions (particularly 32-bit ARM)1Keith Thompson
14 Jan 25      i    `- Re: Calling conventions (particularly 32-bit ARM)1Keith Thompson
10 Jan 25      `* Re: Calling conventions (particularly 32-bit ARM)4David Brown
10 Jan 25       +* Re: Calling conventions (particularly 32-bit ARM)2Thomas Koenig
12 Jan 25       i`- Re: Calling conventions (particularly 32-bit ARM)1David Brown
12 Jan 25       `- Re: Calling conventions (particularly 32-bit ARM)1David Brown

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal