Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connections
Warning: mysqli::query(): Couldn't fetch mysqli in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\index.php on line 66
Article <b8744b4868c5f6b7ef6f629f0fbbf492@www.novabbs.org>
Deutsch   English   Français   Italiano  
<b8744b4868c5f6b7ef6f629f0fbbf492@www.novabbs.org>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: news.eternal-september.org!eternal-september.org!feeder3.eternal-september.org!news.quux.org!news.nk.ca!rocksolid2!i2pn2.org!.POSTED!not-for-mail
From: mitchalsup@aol.com (MitchAlsup1)
Newsgroups: comp.arch
Subject: Re: Calling conventions (particularly 32-bit ARM)
Date: Thu, 9 Jan 2025 20:48:07 +0000
Organization: Rocksolid Light
Message-ID: <b8744b4868c5f6b7ef6f629f0fbbf492@www.novabbs.org>
References: <vlgngv$1ks4a$1@dont-email.me> <4903307dfcce354508c9fc016a4c1ea1@www.novabbs.org> <jwv34htql17.fsf-monnier+comp.arch@gnu.org> <2025Jan8.230846@mips.complang.tuwien.ac.at> <jwvr05cq4tx.fsf-monnier+comp.arch@gnu.org> <2025Jan9.082357@mips.complang.tuwien.ac.at>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Info: i2pn2.org;
	logging-data="2830470"; mail-complaints-to="usenet@i2pn2.org";
	posting-account="o5SwNDfMfYu6Mv4wwLiW6e/jbA93UAdzFodw5PEa6eU";
User-Agent: Rocksolid Light
X-Rslight-Posting-User: cb29269328a20fe5719ed6a1c397e21f651bda71
X-Spam-Checker-Version: SpamAssassin 4.0.0
X-Rslight-Site: $2y$10$ipfCmmwOUjSWpTOR7TEAcOzVT.7Q3FDfmKpGXDHYaqaDdTeTJTr2C

On Thu, 9 Jan 2025 7:23:57 +0000, Anton Ertl wrote:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
> [Someone wrote:]
>>> ABI calling conventions tend to be designed to support at least C,
>>> including varargs and often also tolerant of differences between the
>>> number of arguments in the caller and callee.
>>
>>I can agree that it's important to support those use-cases (varargs
>>obviously, mismatched arg numbers less so),
>
> You are head of a group of people who design a new architecture (say,
> it's 2010 and you design ARM A64, or it's 2014 and you design RISC-V).
> Your ABI designer comes to you and tells you that his life would be
> easier if it was ok that programs with mismatched arguments don't need
> to work.  Would you tell him that they don't need to work?

No, I would stand my ground and mandate that they do work.

> If yes, a few years down the road your prospective customers have to
> decide whether to go for your newfangled architecture or one of the
> established ones.  They learn that a number of programs work
> everywhere else, but not on your architecture.  How many of them will
> be placated by your reasoning that these programs are not strictly
> confoming standard programs?

One of the salient point that allowed C to overtake PASCAL is that
you can write printf() in C while you cannot write write() in PARCAL.
Do not break this assumption on any architecture.

>                               How many will be alarmed by your
> admission that you find it ok that you find it ok that such programs
> don't work on your architecture?  After all, hardly any program is a
> strictly conforming standard program.
>
>>only sloppy ancient C calls
>>functions without proper declarations)
>
> You find it ok to design a calling convention such that ancient C
> programs do not work?

I went the other way, I made an ABI that made varargs EASY !!
and in such a way the caller does not need to know callee is
varargs.

> What benefit do you expect from such a calling convention?  To allow
> to use registers as arguments (and not callee-saved) that would
> otherwise be preferably used as callee-saved registers?

I found no particular problem in passing a fixed number of arguments
in registers and the rest on a stack. va_list; dumps the registers
onto the stack to form a vector of arguments in memory. va_arg
initializes the pointer to where the registers got stuck on the stack.

> However, I wonder why, e.g., RISC-V does not allow the use of all
> caller-saved registers as arguments.

A) we need some registers for passing of arguments, and some
...for returning results.
B) we need some temporary registers so short leaf subroutines
...do not need stack space in order to compute with the given
...arguments
C) we need some registers for holding onto caller's state while
...processing callee operations
D) there is generally a register holding the return address.

Generally (A) and (B) have a sliding window. The fewer arguments
and results, the more temporary registers.

(C) includes FP and SP as callee preserved registers--that is
...when control returns to caller R16..R31 contain the same
...values as when the CALL was performed.

In looking at code out of My 66000 LLVM compiler, there are so
few subroutines with "that many" arguments and results, that
mandating more than 8 arguments or results go through memory
is not really a performance burden.

Also: More callee save registers (preserved) causes more stack
space to be allocated for the 'temporary' registers. Say you want
all the registers (except return address register, and return
result register) to be preserved across a subroutine call: So, a
small subroutine needing 3 registers to perform its calculations;
now has 3 STs and 3 LDs to preserve caller registers, whereas
with temporary registers there is no overhead.

> In addition to the 8 argument
> registers (a0-a7=x10-x17), RISC-V has 7 additional caller-saved
> registers: t0-t6(=x5-x7,x28-x31); for FP register's it's even more
> extreme: 8 argument registers fa0-fa7=f10-f17, and 12 additional
> caller-saved registers ft0-ft12=f0-f7,f28-f31.
>
>>even if it comes at the cost of
>>using different calling conventions for the two cases.
>
> That would mean that you find it ok that existing programs that use
> vararg functions like printf but do not declare them before use don't
> work on your newfangled architecture.  Looking at
> <https://pdos.csail.mit.edu/6.828/2023/readings/riscv-calling.pdf>,
> the RISC-V people find that acceptable:
>
> |If argument i < 8 is a floating-point type, it is passed in
> |floating-point register fai; [...]  Additionally, floating-point
> |arguments to variadic functions (except those that are explicitly
> |named in the parameter list) are passed in integer registers.
>
> So if I 'printf("%f",1.0)' without first declaring printf, the program
> won't work.  I just tried out compiling the following program on
> RISC-V with gcc 10.3.1:
>
> int main()
> {
>   printf("%f\n",1.0);
> }
>
> int xxx()
> {
>   yyy("%f\n",1.0,2);
> }
>
> Note that there is no "#include <stdio.h>" or any declaration of
> printf() or yyy().  Yet 1.0 is passed to printf() in a1, while it is
> passed to yyy() in fa0, and 2 is passed to yyy() in a1.

This is bad...not horrible, but bad.

> And gcc works around the varargs decision by using the varargs calling
> convention for some well-known vararg functions like printf, while
> other undeclared functions use the non-varargs calling convention.
> Apparently the fallout of that decision by the RISC-V people hit a
> "relevant" program.

A good ABI does not need these distinctions.

It also leaves open code compiled partially by GCC from linking with
code
compiled by LLVM will have interoperability issues on mundane calls.

> [1] Apparently they stuck with the decision to deal differently with
> varargs, and then decided to change the rest of the calling convention
> to benefit from that decision by not leaving holes in the FP argument
> registers for integers and vice versa.  I don't find this clearly
> expressed in
> <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc>.
> The only thing that points in that direction is:
>
> |Values are passed in floating-point registers whenever possible,
> |whether or not the integer registers have been exhausted.
>
> But this does not talk about how the integer argument register
> numbering is changed by the "Hardware Floating-point Calling
> Convention".
>
>>> I certainly have a use for as many arguments as the ABI provides,
>>
>>Ah, yes, machine-generated code can always defy intuitions about what
>>is "typical".
>
> While I use a generator for my interpreter engines, many other people
> hand-code them.  They would probably use macros for the function
> declaration and the tail-call, though.  Or maybe a macro that wraps
> the whole payload so that one can easily switch between this technique
> and one of the others.
>
> - anton