This is the mail archive of the mailing list for the newlib project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch for faster memcpy on MIPS

"Ellcey, Steve" <> writes:
> AFAIU, there's something with the register numbers not right for the case,
> but my MIPS-foo is limited to knowing "MIPS" some kind of acronym :-)
> So I've added apinski to the conversation.
> Ciao!
> Steven
> ------------------------
> I think I will add Richard Sandiford too.  I don't know why regdef.h in
> newlib would use the same register names for the EABI as for the N32 and
> 64 bit ABIs but there may be reasons I am not aware of.
> I have reproduced the problem, I am going to try and rebuild after removing
> '|| _MIPS_SIM==_ABIEABI' from regdef.h and see if things build once I
> have done that.

OK, so this has just given me a chance to get on one of my favourite
hobby horses, sorry, but: I don't think using the "soft" register names
gains anything here.  The first four argument GPRs are the same for
all ABIs, and the set of call-clobbered GPRs are the same for all ABIs.
It's one of the few consistent things about the MIPS calling conventions,
and the soft names seem to make things more confusing than they really are.
E.g.  instead of:

#define REG0 t0
#define REG1 t1
#define REG2 t2
#define REG3 t3
#if _MIPS_SIM == _ABIO32
#  define REG4 t4
#  define REG5 t5
#  define REG6 t6
#  define REG7 t7
#  define REG4 ta0
#  define REG5 ta1
#  define REG6 ta2
#  define REG7 ta3

we could simply use the same registers for all ABIs:

#define REG0 $15
#define REG1 $14
#define REG2 $13
#define REG3 $12
#define REG4 $11
#define REG5 $10
#define REG6 $9
#define REG7 $8

which also makes it more obvious that $7 is available if your
function only has 3 arguments.

Er, sorry, back to the original question.  EABI does use 8 argument
registers, so the intention of regdef.h looks good.  There's no
such thing as _ABIEABI though.  For "historical" reasons, the way
to check for EABI is __mips_eabi rather than _MIPS_SIM==_ABIEABI.

_ABIO32 is only defined when o32 is selected, _ABIN32 is only
defined when n32 is selected, etc.  _MIPS_SIM is only defined
for non-EABI ABIs.  So thanks to the "silent 0" preprocessor

   #if _MIPS_SIM == _ABIO32

in the memcpy code evaluates to true for EABI as well as o32, because in
the EABI case neither macro is defined.

That's also why _MIPS_SIM==_ABIEABI works in practice (and why regdef.h
is OK in practice, although pedantically wrong).  _ABIEABI is never defined,
but _MIPS_SIM isn't defined either for EABI, so the condition is true by
default.  (_MIPS_SIM==DOGS_BREAKFAST would also be true.)  These days,
EABI is the only ABI that doesn't define _MIPS_SIM[*] so in practice
it's the only ABI for which _MIPS_SIM==_ABIEABI would be true.

  [*] there used to be another ABI that might not have done either,
      can't remember now...

So regdef.h should technically use a different condition, although it
won't change anything in practice.  The check for o32 and o64:

  #if defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIO64)

is simpler than the one for "n32, n64 or EABI", so I'd be tempted to use
the o32 and o64 test and switch the if and else branches round.

The linux guys decided to retrofit ta0-3 to o32 and o64, treating them
in that case as aliases of t4-7 (although of course these register are
never argument registers for o32 and o64).  gas now has the same change.
It would probably be a good idea to do the same thing in newlib's regdef.h.

After those changes, and if you don't like my alternative REG*
definitions above, you could just use:

#define REG0 t0
#define REG1 t1
#define REG2 t2
#define REG3 t3
#define REG4 ta0
#define REG5 ta1
#define REG6 ta2
#define REG7 ta3



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]