From: Segher Boessenkool
Sent: 24 October 2020 18:29
On Fri, Oct 23, 2020 at 09:28:59PM +0000, David Laight wrote:
quoted
From: Segher Boessenkool
quoted
Sent: 23 October 2020 19:27
On Fri, Oct 23, 2020 at 06:58:57PM +0100, Al Viro wrote:
quoted
On Fri, Oct 23, 2020 at 03:09:30PM +0200, David Hildenbrand wrote:
On arm64 when callee expects a 32bit argument, the caller is *not* responsible
for clearing the upper half of 64bit register used to pass the value - it only
needs to store the actual value into the lower half. The callee must consider
the contents of the upper half of that register as undefined. See AAPCS64 (e.g.
https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#parameter-passing-rules
); AFAICS, the relevant bit is
"Unlike in the 32-bit AAPCS, named integral values must be narrowed by
the callee rather than the caller."
Or the formal rule:
C.9 If the argument is an Integral or Pointer Type, the size of the
argument is less than or equal to 8 bytes and the NGRN is less
than 8, the argument is copied to the least significant bits in
x[NGRN]. The NGRN is incremented by one. The argument has now
been allocated.
So, in essence, if the value is in a 64bit register the calling
code is independent of the actual type of the formal parameter.
Clearly a value might need explicit widening.
No, this says that if you pass a 32-bit integer in a 64-bit register,
then the top 32 bits of that register hold an undefined value.
That's sort of what I meant.
The 'normal' junk in the hight bits will there because the variable
in the calling code is wider.
quoted
I've found a copy of the 64 bit arm instruction set.
Unfortunately it is alpha sorted and repetitive so shows none
of the symmetry and makes things difficult to find.
All of this is ABI, not ISA. Look at the AAPCS64 pointed to above.
quoted
But, contrary to what someone suggested most register writes
(eg from arithmetic) seem to zero/extend the high bits.
Everything that writes a "w" does, yes. But that has nothing to do with
the parameter passing rules, that is ABI. It just means that very often
a 32-bit integer will be passed zero-extended in a 64-bit register, but
that is just luck (or not, it makes finding bugs harder ;-) )
Working out why the code is wrong is more of an ISA issue than an ABI one.
It may be an ABI one, but the analysis is ISA.
I've written a lot of asm over the years - decoding compiler generated
asm isn't that hard.
At least ARM doesn't have annulled delay slots.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)