tinycc-devel
[Top][All Lists]
Advanced

[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

Attachment: signature.asc
Description: This is a digitally signed message part.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]