On Fri, 25 Jan 2013, Richard Sandiford wrote:

> >  FWIW, I think the benefit from these attributes being a type property is 
> > questionable to say the least.  My understanding is the only application 
> > is to prevent the tail-call optimisation from being applied to non-PIC 
> > standard MIPS functions that otherwise would have to make a direct jump to 
> > MIPS16 code for which there is no hardware support (note that there is no 
> > issue with PIC code as with register jumps the ISA bit can be freely set 
> > at will as required).
> 
> I think the main benefit was more to avoid unnecessary hard-float
> interworking cruft.  If you're calling an indirect function (including
> vtable function) whose type has a mips16 attribute, you know that
> float values will be returned in GPRs without going through the
> libgcc stub.  So...
> 
> >  If that is the case, then perhaps producing a suitable call thunk 
> > instead, similar to these we use to pass floating-point arguments around 
> > with MIPS16 functions or to call PIC code from non-PIC code statically 
> > linked together, so that all standard MIPS code is link-time compatible 
> > with MIPS16 would be a better option?
> 
> ...I think the idea was to avoid this kind of overhead.

 OK, I see, I think it makes some sense I admit.  However in this case I 
think this should be a one-way enforcement, in that the presence of either 
attribute on a prototype would enforce a particular implementation, but 
any implementation would suit a prototype with neither attribute, in which 
case any caller could of course make no assumptions about the callee.

 I.e. these would be valid:

void foo (void);
void foo (void) {}

void __attribute__ ((mips16)) foo (void);
void __attribute__ ((mips16)) foo (void) {}

void __attribute__ ((nomips16)) foo (void);
void __attribute__ ((nomips16)) foo (void) {}

these would also be valid:

void foo (void);
void __attribute__ ((mips16)) foo (void) {}

void foo (void);
void __attribute__ ((nomips16)) foo (void) {}

but these would be invalid:

void __attribute__ ((mips16)) foo (void);
void __attribute__ ((nomips16)) foo (void) {}

void __attribute__ ((nomips16)) foo (void);
void __attribute__ ((mips16)) foo (void) {}

as would be incompatible prototypes:

void foo (void);
void __attribute__ ((mips16)) foo (void);

void foo (void);
void __attribute__ ((nomips16)) foo (void);

void __attribute__ ((mips16)) foo (void);
void __attribute__ ((nomips16)) foo (void);

and these might be invalid as well (debatable though):

void __attribute__ ((mips16)) foo (void);
void foo (void) {}

void __attribute__ ((nomips16)) foo (void);
void foo (void) {}

> But like I say, I might be misrepresenting things, and I'm certainly open
> to removing the check if there's agreement we don't want type attributes.

 The origin of the choice may have been lost in the mist of history I am 
afraid, and I'd be happy to know what it was if there's still someone 
around here who might be able to bring it back.  I wasn't involved with 
any of the original MIPS16 GCC stuff.

> FWIW, there's also the "target" attribute, which is designed specifically
> for turning options on and off at the function definition site, and which
> also has an associated pragma for controlling a block of functions.
> That isn't implemented yet for MIPS, but should be.  E.g. we could have
> target("mips16"), target("no-mips16"), target("micromips") and
> target("no-micromips").
> 
> So one alternative might be to keep the current attributes as they are
> and implement "target".

 That might make sense too; of course settings conflicting with the 
corresponding attribute would have to be diagnosed and rejected.

  Maciej

Reply via email to