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