[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] Struct and float parameter passing ir arm-gen.c
From: |
Thomas Preud'homme |
Subject: |
Re: [Tinycc-devel] Struct and float parameter passing ir arm-gen.c |
Date: |
Fri, 28 Oct 2011 14:24:30 +0200 |
User-agent: |
KMail/1.13.7 (Linux/3.0.0-1-amd64; KDE/4.6.5; x86_64; ; ) |
Le vendredi 28 octobre 2011 01:19:50, Daniel Glöckner a écrit :
> Hi,
>
> On Fri, Oct 28, 2011 at 12:08:55AM +0200, Thomas Preud'homme wrote:
> > I've been reading arm-gen.c lately and was a bit surprised by some code
> > related to struct and float (including double and long double) parameter
> > passing in gfunc_call. It's probably just a mistake from my reading in
> > which case I'd appreciate you explained me the bits I missed.
> >
> > As I understand it [0], the array /plan/ is used to memorize the
> > association
> >
> > between parameters and the register(s) in which they are passed. The
> > association is done via a line plan[nb_args-1-i][1]=args_size/4; in a
> > switch case done in the second for loop browsing the parameter.
> >
> > [0] From lines like:
> > s=regmask(plan[nb_args-i-1][1]; and:
> > todo&=~(1<<plan[nb_args-i-1][1]) with TODO being used to generate ldm
> >
> > instruction later.
> >
> > What bothers me is that the association is only done in the general case
> > (type != float, double, long double and struct) but args_size is
> > increased in general case *and* struct + floats case. This mean that if
> > the first parameter of a function is a structure of size 8 bytes, then
> > core registers r0 and r1 are skipped although they could be used by
> > following integer parameter.
>
> did you see the o(0xE8BD0000|todo); line further down?
> It pulls all parameters that should reside in core registers back from the
> stack right before calling the function. This includes structs and floats.
Yep I saw it. It's the ldm I was talking about in the [0] note. I think I've
found the mistake I did: I read todo|= (1<<plan[nb_args-i-1][1]); instead of
the todo&=~(1<<plan[nb_args-i-1][1]); which was written. Sorry for the noise.
>
> > It's also in opposition to what require stage C in chapter 5.5 of AAPCS
> > documentation. Basically it says either a type qualify for co-processor
> > register in which case it's passed in co-processor register or on stack
> > but without touching NCRN (Next Core Register Number). Or it does not
> > qualify for co-processor register (for example if there is no
> > co-processor like when tcc produce code compatible with system without
> > VFP, ie TCC_ARM_VFP is undefined) and is allocated one or several core
> > register (and can be half on registers and half on stack).
>
> Values are simply not passed in floating point registers. That's how it was
> done with OABI on my Zaurus when I wrote gfunc_call and that's how it is
> done nowadays with EABI.
Yep I saw it.
>
> TCC_ARM_VFP without TCC_ARM_EABI should ideally be equivalent to GCC with
> -mfpu=vfp -mfloat-abi=hard, but it isn't. I doubt anyone uses TCC if he
> is trading EABI compatibility for floating point performance.
I respectly disagree here. I don't think people who care about performance use
tcc at all, whatever the ABI is. Tcc is very fast to compile things, has a low
memory footprint (never measured but I'm pretty sure I'm right), and is able
to run C source code like script. Since these things have nothing to do with
performance, I believe even on hardfloat systems, tcc makes sense. For example,
it could be used as a compiler to test the compilation of a project at every
commit.
>
> Best regards,
Thanks a lot for pointing out my mistake.
Best regards,
>
> Daniel
Thomas Preud'homme
signature.asc
Description: This is a digitally signed message part.