[PATCH] - Use of powerpc 64bit instructions in 32bit ABI

Ian Lance Taylor ian@wasabisystems.com
Thu Oct 16 04:55:00 GMT 2003


David Edelsohn <dje@watson.ibm.com> writes:

> >>>>> Richard Henderson writes:
> 
> >> Apple patch keeps 64bit values in GPRs. If this can be accomplished without
> >> changes to common part please let us know how sparc port accomplishes this.
> 
> Richard> By letting HARD_REGNO_MODE_OK return true for DImode.
> 
> 	Okay, we're going to play 20 Questions.  Why didn't you say so! :-)
> 
> 	If I understand correctly, you are recommending keeping
> BITS_PER_WORD as 32 but allowing HARD_REGNO_OK to return true for 64-bit
> modes in GPRs for the option that enables 64-bit instructions.
> HARD_REGNO_OK only affects register allocation and not argument passing
> because function_arg directly generates and advances hard registers?

Richard, I'm not trying to be irritating, but the SPARC code is not a
great example.

I can see that if I build a SPARC compiler, I can compile with -m32
-mv8plus -mcpu=v9 and the resulting code is ABI compatible with code
compiled with, e.g., -m32 -mcpu=v7.  When a function passes a long
long value, it is passed in two registers.  But the resulting 64-bit
code is pretty bad.

Or I can compile with -m64 -mv8plus -mcpu=v9, but the resulting code
is not ABI compatible with code compiled with -mcpu=v7.  A long long
value is passed in a single register.

With -m32 -mv8plus -mcpu=v9, 64-bit values are loaded using ldd rather
than ldx, and are then put back together into a single register.  It
would be more efficient to use ldx.  64-bit multiplication is done
using a several instruction sequence to put two 32 bit values into a
single register, do the multiplication, and then pull the result
apart.  This happens for each multiplication even when several long
long values are multiplied together.  It would be more efficient to
leave the value in a 64-bit register and just use mulx.

It's true that with -m32 -mv8plus -mcpu=v9 HARD_REGNO_MODE_OK will
return true for DImode.  But HARD_REGNO_NREGS (r, DImode) will return
2 for all registers.  In other words, a DImode value will be stored in
two registers, even though the registers can hold 64-bit values.

For efficient 64-bit code, you want HARD_REGNO_NREGS (r, DImode) to
return 1.  But you also want to pass a 64-bit value in two registers,
to maintain ABI compatibility.  That means that you need a way to tell
the function calling sequence to split a 64-bit value into two 32-bit
values.

That of course can be done by having FUNCTION_ARG returning a
PARALLEL.  So, David (Edelsohn), I think that what you want is to
define HARD_REGNO_NREGS (r, DImode) to return 1 for a 64-bit register,
but also have FUNCTION_ARG return an appropriate PARALLEL when passing
a 64-bit value.  When passing a 32-bit value FUNCTION_ARG can just
return a REG as usual.

I think the SPARC -mv8plus -mcpu=v9 support could be improved greatly
for 64-bit values by doing this as well.

Ian



More information about the Gcc-patches mailing list