Re: Help with an ABI peculiarity

2022-01-21 Thread Richard Sandiford via Gcc
Iain Sandoe  writes:
> Hi Richard,
>> On 20 Jan 2022, at 22:32, Richard Sandiford  
>> wrot>> Iain Sandoe  writes:
 On 10 Jan 2022, at 10:46, Richard Sandiford  
 wrot>> An alternative might be to make promote_function_arg a “proper”
 ABI hook, taking a cumulative_args_t and a function_arg_info.
 Perhaps the return case should become a separate hook at the
 same time.
 
 That would probably require more extensive changes than just
 updating the call sites, and I haven't really checked how much
 work it would be, but hopefully it wouldn't be too bad.
 
 The new hook would still be called before function_arg, but that
 should no longer be a problem, since the new hook arguments would
 give the target the information it needs to decide whether the
 argument is passed in registers.
>>> 
>>> Yeah, this was my next port of call (I have looked at it ~10 times and then
>>> decided “not today, maybe there’s a simpler way”).
>
> … and I did not have a chance to look at this in the meantime …
>
>> BTW, finally catching up on old email, I see this is essentially also
>> the approach that Maxim was taking with the TARGET_FUNCTION_ARG_BOUNDARY
>> patches.  What's the situation with those? 
>
> I have the patches plus amendments to make use of their new functionality on 
> the
> development branch, which is actually in pretty good shape (not much 
> difference
> in testsuite results from other Darwin sub-ports).
>
> Maxim and I need to discuss amending the TARGET_FUNCTION_ARG_BOUNDARY
> changes to account for Richard (B)’s comments.
>
> Likewise, I need to tweak the support for heap allocation of nested function 
> trampolines
> to account for review comments.

Sounds great.

> As always, it’s a question of fitting everything in…

Yeah :-)  The question probably sounded pushier than it was meant to,
sorry.  I just wanted to check that you or Maxim weren't still waiting
on reviews.

Richard


Re: Help with an ABI peculiarity

2022-01-21 Thread Iain Sandoe
Hi Richard,

> On 20 Jan 2022, at 22:32, Richard Sandiford  wrote:
> 
> Iain Sandoe  writes:
>>> On 10 Jan 2022, at 10:46, Richard Sandiford  
>>> wrot>> An alternative might be to make promote_function_arg a “proper”
>>> ABI hook, taking a cumulative_args_t and a function_arg_info.
>>> Perhaps the return case should become a separate hook at the
>>> same time.
>>> 
>>> That would probably require more extensive changes than just
>>> updating the call sites, and I haven't really checked how much
>>> work it would be, but hopefully it wouldn't be too bad.
>>> 
>>> The new hook would still be called before function_arg, but that
>>> should no longer be a problem, since the new hook arguments would
>>> give the target the information it needs to decide whether the
>>> argument is passed in registers.
>> 
>> Yeah, this was my next port of call (I have looked at it ~10 times and then
>> decided “not today, maybe there’s a simpler way”).

… and I did not have a chance to look at this in the meantime …

> BTW, finally catching up on old email, I see this is essentially also
> the approach that Maxim was taking with the TARGET_FUNCTION_ARG_BOUNDARY
> patches.  What's the situation with those? 

I have the patches plus amendments to make use of their new functionality on the
development branch, which is actually in pretty good shape (not much difference
in testsuite results from other Darwin sub-ports).

Maxim and I need to discuss amending the TARGET_FUNCTION_ARG_BOUNDARY
changes to account for Richard (B)’s comments.

Likewise, I need to tweak the support for heap allocation of nested function 
trampolines
to account for review comments.

As always, it’s a question of fitting everything in…
thanks
Iain



Re: Help with an ABI peculiarity

2022-01-20 Thread Richard Sandiford via Gcc
Iain Sandoe  writes:
>> On 10 Jan 2022, at 10:46, Richard Sandiford  
>> wrot>> An alternative might be to make promote_function_arg a “proper”
>> ABI hook, taking a cumulative_args_t and a function_arg_info.
>> Perhaps the return case should become a separate hook at the
>> same time.
>> 
>> That would probably require more extensive changes than just
>> updating the call sites, and I haven't really checked how much
>> work it would be, but hopefully it wouldn't be too bad.
>> 
>> The new hook would still be called before function_arg, but that
>> should no longer be a problem, since the new hook arguments would
>> give the target the information it needs to decide whether the
>> argument is passed in registers.
>
> Yeah, this was my next port of call (I have looked at it ~10 times and then
> decided “not today, maybe there’s a simpler way”).

BTW, finally catching up on old email, I see this is essentially also
the approach that Maxim was taking with the TARGET_FUNCTION_ARG_BOUNDARY
patches.  What's the situation with those?  Sorry for not responding
to them earlier.

Thanks,
Richard


Re: Help with an ABI peculiarity

2022-01-11 Thread Eric Gallager via Gcc
On Mon, Jan 10, 2022 at 8:28 AM Iain Sandoe  wrote:
>
> Hi Florian,
>
> > On 10 Jan 2022, at 08:38, Florian Weimer  wrote:
> >
> > * Jeff Law via Gcc:
> >
> >> Most targets these days use registers for parameter passing and
> >> obviously we can run out of registers on all of them.  The key
> >> property is the size/alignment of the argument differs depending on if
> >> it's pass in a register (get promoted) or passed in memory (not
> >> promoted).  I'm not immediately aware of another ABI with that
> >> feature.  Though I haven't really gone looking.
> >
> > I think what AArch64 Darwin does is not compatible with a GCC extension
> > that allows calling functions defined with a prototype without it (for
> > pre-ISO-C compatibility).
>
> AFAIU the implementation:
>
> In the case that a call is built and no prototype is available, the 
> assumption is
> that all parms are named.  The promotion is then done according to the C
> promotion rules.
>
> [for the number of args that can be passed in int regs] the callee will 
> happen to
> observe the same rules in this case.
>
> It will, however, break once we overflow the number of int regs.. :/
>
> 
>
> The case that is fundamentally broken from scratch is of a variadic function
> called without a prototype - since the aarch64-darwin ABI places unnamed
> parms differently.
>
> So that the absence of a prototype causes us to place all args as if they were
> named.
>
> 
>
> Wmissing-prototype
> Wstrict-prototypes
>
> would wisely be promoted to errors for this platform,

Relevant bugs in this area:
82922, add -Wstrict-prototypes to -Wextra:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82922
91092, Error on implicit function declarations by default:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91092
(and the related bugs in the "See Also", "Depends On", "Duplicates",
etc. fields for each of them)

>
> (the ABI is obviously not up for change, since it’s already on millions of 
> devices).
>
> >  Given that, anyone defining an ABI in
> > parallel with a GCC implementation probably has paused, reconsidered
> > what they were doing,
>
> My guess is that this step was omitted - i.e. the port was designed in the 
> LLVM
> framework.  I can raise a query with the ABI owners, I guess.
>
> >  and adjusted the ABI for K compatibility.
>
> FWIW, we bootstrap sucessfully including the K code in intl/
> Given we have 8 int regs available, probably many calls will work ..
>
> 
>
> As of now, I must assume that what is broken by the cases above will remain
> broken, and I just need to find a way to implement the cases that will work 
> (i.e.
> when proper prototypes are available)
>
> thanks
> Iain
>


Re: Help with an ABI peculiarity

2022-01-11 Thread Richard Earnshaw via Gcc




On 10/01/2022 08:38, Florian Weimer via Gcc wrote:

* Jeff Law via Gcc:


Most targets these days use registers for parameter passing and
obviously we can run out of registers on all of them.  The key
property is the size/alignment of the argument differs depending on if
it's pass in a register (get promoted) or passed in memory (not
promoted).  I'm not immediately aware of another ABI with that
feature.  Though I haven't really gone looking.


I think what AArch64 Darwin does is not compatible with a GCC extension
that allows calling functions defined with a prototype without it (for
pre-ISO-C compatibility).  Given that, anyone defining an ABI in
parallel with a GCC implementation probably has paused, reconsidered
what they were doing, and adjusted the ABI for K compatibility.

Thanks,
Florian



Not having a prototype was deprecated in C89.  One would hope that after 
33 years we could move on from that.


R.


Re: Help with an ABI peculiarity

2022-01-10 Thread Florian Weimer via Gcc
* Iain Sandoe:

> In the case that a call is built and no prototype is available, the
> assumption is that all parms are named.  The promotion is then done
> according to the C promotion rules.
>
> [for the number of args that can be passed in int regs] the callee
> will happen to observe the same rules in this case.
>
> It will, however, break once we overflow the number of int regs.. :/

Exactly.

> The case that is fundamentally broken from scratch is of a variadic function
> called without a prototype - since the aarch64-darwin ABI places unnamed
> parms differently.

That part is true for powerpc64le as well, due to the caller-provided
saved parameter area which only exists with variadic calls.  This
already happens in very simple cases, like the POSIX open function.  The
corruption is quite difficult to diagnose, too. 8-(  But it's also
quite rare to see such bugs.

> Given we have 8 int regs available, probably many calls will work .. 

Oh, I didn't know that so many registers were available.  Maybe that's
enough to paper over the lack of ABI compatibility for now.  Presumably
you could count the number of arguments and emit a warning at least?

C++ metaprogramming involving many parameters tends to use variadic
templates of non-variadic functions, so that shouldn't be a problem.

Thanks,
Florian



Re: Help with an ABI peculiarity

2022-01-10 Thread Iain Sandoe
Hi Florian,

> On 10 Jan 2022, at 08:38, Florian Weimer  wrote:
> 
> * Jeff Law via Gcc:
> 
>> Most targets these days use registers for parameter passing and
>> obviously we can run out of registers on all of them.  The key
>> property is the size/alignment of the argument differs depending on if
>> it's pass in a register (get promoted) or passed in memory (not
>> promoted).  I'm not immediately aware of another ABI with that
>> feature.  Though I haven't really gone looking.
> 
> I think what AArch64 Darwin does is not compatible with a GCC extension
> that allows calling functions defined with a prototype without it (for
> pre-ISO-C compatibility).

AFAIU the implementation:

In the case that a call is built and no prototype is available, the assumption 
is
that all parms are named.  The promotion is then done according to the C
promotion rules.

[for the number of args that can be passed in int regs] the callee will happen 
to
observe the same rules in this case.

It will, however, break once we overflow the number of int regs.. :/



The case that is fundamentally broken from scratch is of a variadic function
called without a prototype - since the aarch64-darwin ABI places unnamed
parms differently.

So that the absence of a prototype causes us to place all args as if they were
named.



Wmissing-prototype
Wstrict-prototypes

would wisely be promoted to errors for this platform,

(the ABI is obviously not up for change, since it’s already on millions of 
devices).

>  Given that, anyone defining an ABI in
> parallel with a GCC implementation probably has paused, reconsidered
> what they were doing,

My guess is that this step was omitted - i.e. the port was designed in the LLVM
framework.  I can raise a query with the ABI owners, I guess.

>  and adjusted the ABI for K compatibility.

FWIW, we bootstrap sucessfully including the K code in intl/
Given we have 8 int regs available, probably many calls will work .. 



As of now, I must assume that what is broken by the cases above will remain
broken, and I just need to find a way to implement the cases that will work 
(i.e.
when proper prototypes are available)

thanks
Iain



Re: Help with an ABI peculiarity

2022-01-10 Thread Iain Sandoe



> On 10 Jan 2022, at 10:46, Richard Sandiford  wrote:
> 
> Iain Sandoe  writes:
>> Hi Folks,
>> 
>> In the aarch64 Darwin ABI we have an unusual (OK, several unusual) feature 
>> of the calling convention.
>> 
>> When an argument is passed *in a register* and it is integral and less than 
>> SI it is promoted (with appropriate signedness) to SI.  This applies when 
>> the function parm is named only.
>> 
>> When the same argument would be placed on the stack (i.e. we ran out of 
>> registers) - it occupies its natural size, and is naturally aligned (so, for 
>> instance, 3 QI values could be passed as 3 registers - promoted to SI .. or 
>> packed into three adjacent bytes on the stack)..
>> 
>> The key is that we need to know that the argument will be placed in a 
>> register before we decide whether to promote it.
>> (similarly, the promotion is not done in the callee for the in-register 
>> case).
>> 
>> I am trying to figure out where to implement this.
>> 
>> * the code that (in regular cases) decides on such promotions is called 
>> _before_ we call target’s function_arg.
>> 
>> * OVERRIDE_ABI_FORMAT seems to be called too early (we don’t have enough 
>> information on the function - to decide to set the PARM passed-as type).
>> 
>> I’ve experimented with various schemes - specifically that  tm.function_arg 
>> can alter the mode of the register in the appropriate cases, and then 
>> calls.c can act on the case that the mode has been changed by that callback.
>> 
>> It seems probable that this approach can be made non-invasive - but...
>> ... if someone can point me at a better solution - I’m interested.
> 
> I agree there doesn't seem to be an out-of-the-box way of doing this.
> I'm not sure about having two different ways of specifying promotion
> though.  (For one thing, it should be possible to query promotion
> without generating “garbage” rtl.)

In this case, it does not appear to be possible to do that without the
cumulative args info .. so your next point is the logical design.

> An alternative might be to make promote_function_arg a “proper”
> ABI hook, taking a cumulative_args_t and a function_arg_info.
> Perhaps the return case should become a separate hook at the
> same time.
> 
> That would probably require more extensive changes than just
> updating the call sites, and I haven't really checked how much
> work it would be, but hopefully it wouldn't be too bad.
> 
> The new hook would still be called before function_arg, but that
> should no longer be a problem, since the new hook arguments would
> give the target the information it needs to decide whether the
> argument is passed in registers.

Yeah, this was my next port of call (I have looked at it ~10 times and then
decided “not today, maybe there’s a simpler way”).

thanks
Iain



Re: Help with an ABI peculiarity

2022-01-10 Thread Richard Sandiford via Gcc
Iain Sandoe  writes:
> Hi Folks,
>
> In the aarch64 Darwin ABI we have an unusual (OK, several unusual) feature of 
> the calling convention.
>
> When an argument is passed *in a register* and it is integral and less than 
> SI it is promoted (with appropriate signedness) to SI.  This applies when the 
> function parm is named only.
>
> When the same argument would be placed on the stack (i.e. we ran out of 
> registers) - it occupies its natural size, and is naturally aligned (so, for 
> instance, 3 QI values could be passed as 3 registers - promoted to SI .. or 
> packed into three adjacent bytes on the stack)..
>
> The key is that we need to know that the argument will be placed in a 
> register before we decide whether to promote it.
> (similarly, the promotion is not done in the callee for the in-register case).
>
> I am trying to figure out where to implement this.
>
> * the code that (in regular cases) decides on such promotions is called 
> _before_ we call target’s function_arg.
>
> * OVERRIDE_ABI_FORMAT seems to be called too early (we don’t have enough 
> information on the function - to decide to set the PARM passed-as type).
>
> I’ve experimented with various schemes - specifically that  tm.function_arg 
> can alter the mode of the register in the appropriate cases, and then calls.c 
> can act on the case that the mode has been changed by that callback.
>
> It seems probable that this approach can be made non-invasive - but...
> ... if someone can point me at a better solution - I’m interested.

I agree there doesn't seem to be an out-of-the-box way of doing this.
I'm not sure about having two different ways of specifying promotion
though.  (For one thing, it should be possible to query promotion
without generating “garbage” rtl.)

An alternative might be to make promote_function_arg a “proper”
ABI hook, taking a cumulative_args_t and a function_arg_info.
Perhaps the return case should become a separate hook at the
same time.

That would probably require more extensive changes than just
updating the call sites, and I haven't really checked how much
work it would be, but hopefully it wouldn't be too bad.

The new hook would still be called before function_arg, but that
should no longer be a problem, since the new hook arguments would
give the target the information it needs to decide whether the
argument is passed in registers.

Thanks,
Richard


Re: Help with an ABI peculiarity

2022-01-10 Thread Florian Weimer via Gcc
* Jeff Law via Gcc:

> Most targets these days use registers for parameter passing and
> obviously we can run out of registers on all of them.  The key
> property is the size/alignment of the argument differs depending on if
> it's pass in a register (get promoted) or passed in memory (not
> promoted).  I'm not immediately aware of another ABI with that
> feature.  Though I haven't really gone looking.

I think what AArch64 Darwin does is not compatible with a GCC extension
that allows calling functions defined with a prototype without it (for
pre-ISO-C compatibility).  Given that, anyone defining an ABI in
parallel with a GCC implementation probably has paused, reconsidered
what they were doing, and adjusted the ABI for K compatibility.

Thanks,
Florian



Re: Help with an ABI peculiarity

2022-01-08 Thread Jeff Law via Gcc




On 1/7/2022 2:55 PM, Paul Koning via Gcc wrote:



On Jan 7, 2022, at 4:06 PM, Iain Sandoe  wrote:

Hi Folks,

In the aarch64 Darwin ABI we have an unusual (OK, several unusual) feature of 
the calling convention.

When an argument is passed *in a register* and it is integral and less than SI 
it is promoted (with appropriate signedness) to SI.  This applies when the 
function parm is named only.

When the same argument would be placed on the stack (i.e. we ran out of 
registers) - it occupies its natural size, and is naturally aligned (so, for 
instance, 3 QI values could be passed as 3 registers - promoted to SI .. or 
packed into three adjacent bytes on the stack)..

The key is that we need to know that the argument will be placed in a register 
before we decide whether to promote it.
(similarly, the promotion is not done in the callee for the in-register case).

I am trying to figure out where to implement this.

I don't remember the MIPS machinery well enough, but is that a similar case?  
It too has register arguments (4 or 8 of them) along with stack arguments (for 
the rest).
Most targets these days use registers for parameter passing and 
obviously we can run out of registers on all of them.  The key property 
is the size/alignment of the argument differs depending on if it's pass 
in a register (get promoted) or passed in memory (not promoted).  I'm 
not immediately aware of another ABI with that feature.  Though I 
haven't really gone looking.


jeff


Re: Help with an ABI peculiarity

2022-01-07 Thread Paul Koning via Gcc



> On Jan 7, 2022, at 4:06 PM, Iain Sandoe  wrote:
> 
> Hi Folks,
> 
> In the aarch64 Darwin ABI we have an unusual (OK, several unusual) feature of 
> the calling convention.
> 
> When an argument is passed *in a register* and it is integral and less than 
> SI it is promoted (with appropriate signedness) to SI.  This applies when the 
> function parm is named only.
> 
> When the same argument would be placed on the stack (i.e. we ran out of 
> registers) - it occupies its natural size, and is naturally aligned (so, for 
> instance, 3 QI values could be passed as 3 registers - promoted to SI .. or 
> packed into three adjacent bytes on the stack)..
> 
> The key is that we need to know that the argument will be placed in a 
> register before we decide whether to promote it.
> (similarly, the promotion is not done in the callee for the in-register case).
> 
> I am trying to figure out where to implement this.

I don't remember the MIPS machinery well enough, but is that a similar case?  
It too has register arguments (4 or 8 of them) along with stack arguments (for 
the rest).

paul




Help with an ABI peculiarity

2022-01-07 Thread Iain Sandoe
Hi Folks,

In the aarch64 Darwin ABI we have an unusual (OK, several unusual) feature of 
the calling convention.

When an argument is passed *in a register* and it is integral and less than SI 
it is promoted (with appropriate signedness) to SI.  This applies when the 
function parm is named only.

When the same argument would be placed on the stack (i.e. we ran out of 
registers) - it occupies its natural size, and is naturally aligned (so, for 
instance, 3 QI values could be passed as 3 registers - promoted to SI .. or 
packed into three adjacent bytes on the stack)..

The key is that we need to know that the argument will be placed in a register 
before we decide whether to promote it.
(similarly, the promotion is not done in the callee for the in-register case).

I am trying to figure out where to implement this.

* the code that (in regular cases) decides on such promotions is called 
_before_ we call target’s function_arg.

* OVERRIDE_ABI_FORMAT seems to be called too early (we don’t have enough 
information on the function - to decide to set the PARM passed-as type).

I’ve experimented with various schemes - specifically that  tm.function_arg can 
alter the mode of the register in the appropriate cases, and then calls.c can 
act on the case that the mode has been changed by that callback.

It seems probable that this approach can be made non-invasive - but...
... if someone can point me at a better solution - I’m interested.

thanks
Iain