As I mentioned in above, there is a design doc for it which explains all
that, but the gist is that this automatically applies the rules of a given
ABI to marshal arguments from and dispatch return values to a ThreadContext
based on their types. So for instance, if you have a function like:

int foo(int, float);

It will find a rule that matches int arguments to extract that value, then
find a rule that matches float arguments, then pass those two arguments to
foo, then take the return value from foo and find a rule that tells it how
to store an int return result and do that.

There is a unit test here:

https://gem5-review.googlesource.com/c/public/gem5/+/23197
<https://gem5-review.googlesource.com/c/public/gem5/+/23197/5>

which will show it in action and probably help it make sense.

There are a few motivations behind this. First, there are currently four
different mechanisms for gathering arguments for functions implemented in
gem5 but called from within a simulation.

1. Gathering arguments directly within an instruction like a pseudo inst.
2. System call arguments and return values.
3. The getArgument mechanism, also used by pseudo insts and some kernel
intercepts like the one for udelay.
4. The Arguments class built on getArgument.

A big problem with all of these is that they try (when they try) to capture
important aspects of an argument (is it big enough to take two registers?
How many resources have been used so far? Is this FP or int?), but there is
no bounded list of what matters when locating and extracting arguments or
setting return values. Also these extra qualities are inconsistently
applied, there generally isn't any support for arguments spilled to the
stack, everything is implemented several times, there's a lot of blurred or
ignored lines as far as what applies to a particular OS, what applies to
system calls, and what applies to user code. It also exposes global ISA
level state like what register the first argument should go in (not
universal, not necessarily well defined, and a global ISA dependency).

On top of all this, with the exception of the system call mechanism which
has a dependency on the overburdened Process type, there is no support for
having different ABIs in place at the same time. For instance on x86 in
linux, I found some documentation online which claims that a system called
made with int 0x80 gets its arguments from a different place than one that
uses the syscall instruction, even within the same process. See here:

https://en.wikibooks.org/wiki/X86_Assembly/Interfacing_with_Linux

This is actually impossible today since there is one hook for getting
system call arguments and it can't distinguish between these two cases.

The reason I decided to wade into this particular swamp and start cleaning
things up was actually that when dealing with the ARM fast model CPUs,
there is no way to trigger behavior outside of the CPU in the context of a
particular CPU and not an entire model (which is often a cluster of cores)
except semihosting instructions. These must use registers in a way that's
incompatible with how they work when called from instructions, so either
they would have to stuff registers in the right places after the fact so
the pseudo inst could find them, or they could tell the pseudo insts (via a
pluggable ABI) how to find the arguments they need.

That is also not yet considering the stack of mechanisms that would be
needed to enable system call emulation on fast models, ie a semihosting
call triggering a pseudo inst triggering a system call, where the system
call needs to get its arguments from a different place than normal.

So, rather than have a simplistic and simplistically applied mechanism for
getting function arguments out of a ThreadContext, I made a system which
more or less makes the compiler figure it out and lets an ABI define
whatever rules it needs to based on, for instance, int vs floating point,
size of type, structures vs arrays vs unions, alignments of arguments on
the stack, large return values which need special allocation and are a
virtual first argument, etc.

If you want to see some examples of system calls which take advantage of
this mechanism, there are many examples in this CL:

https://gem5-review.googlesource.com/c/public/gem5/+/23193
<https://gem5-review.googlesource.com/c/public/gem5/+/23193/5>

As you can see, the implementation of the system calls gets simpler, not
more complicated. Instead of having to fish out arguments themselves, they
just accept arguments like normal functions do and it's all handled
automatically.

A more or less complete implementation of the ARM 64 bit ABI (with a caveat
mentioned in the commit message) can be found in this CL.

https://gem5-review.googlesource.com/c/public/gem5/+/23751

Gabe

On Tue, Dec 17, 2019 at 9:26 AM Jason Lowe-Power <[email protected]>
wrote:

> Hey Gabe,
>
> Sorry for not looking into these much so far. Honestly, I've been
> intimidated by the huge length of the patch chain and the complexity of the
> code.
>
> Could you explain in more detail here or on the Jira issue what's going on?
> https://gem5.atlassian.net/browse/GEM5-187 I'd like to understand better
> the need for the complexity of this code and why it can't be implemented in
> a simpler way. I'd also like to understand what the high level changes are
> going to be. What will the API be at the end of all of these changes? How
> are these changes going to affect our end users?
>
> I guess the GuestABI stuff has all passed me by. I'm not sure I understand
> guest_abi.hh *at all*. What's this code doing? Why does it need so many
> levels of template arguments?
>
> I'm generally concerned with the complexity of this code. It's going to be
> a nightmare to try to debug a system call or a pseudo instruction with gdb
> given all of these templated functions (and even a recursive template
> function in guest_abi.hh!).
>
> Thanks,
> Jason
>
> On Mon, Dec 16, 2019 at 11:02 PM Gabe Black <[email protected]> wrote:
>
> > Hi folks. I have a lot of pending CLs in flight right now, I think about
> 70
> > of which are currently active. That's a lot, so I thought I'd point out
> the
> > ones which, from my perspective, are the highest priority.
> >
> > Top priority would be this one, the next one in my GuestABI series:
> >
> > https://gem5-review.googlesource.com/c/public/gem5/+/23178
> >
> > After that are the 6 GDB related ones currently starting here:
> >
> > https://gem5-review.googlesource.com/c/public/gem5/+/22118
> >
> > Giacomo has been doing a great job reviewing those so far, but we're
> still
> > crunching through them.
> >
> > Finally, it would be nice to get this one in to close out it's little
> > peripheral series:
> >
> > https://gem5-review.googlesource.com/c/public/gem5/+/23361
> >
> > Beyond that plowing into the remaining 60 or so GuestABI patches would be
> > great. I've got a design doc for that mechanism which will hopefully make
> > the rounds internally in the near future, and then I'll share it on
> > gem5-dev to give folks a better idea of what's going on without having to
> > decipher the code itself.
> >
> > But to reiterate, the top priority for me is that first one above.
> Getting
> > that in is blocking some other work I'm trying to do with Fast Model, so
> > sooner would be better than later.
> >
> > Gabe
> > _______________________________________________
> > gem5-dev mailing list
> > [email protected]
> > http://m5sim.org/mailman/listinfo/gem5-dev
> _______________________________________________
> gem5-dev mailing list
> [email protected]
> http://m5sim.org/mailman/listinfo/gem5-dev
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to