This is the mail archive of the
mailing list for the GCC project.
Re: [PATCH] - Use of powerpc 64bit instructions in 32bit ABI
- From: Ian Lance Taylor <ian at wasabisystems dot com>
- To: David Edelsohn <dje at watson dot ibm dot com>
- Cc: Richard Henderson <rth at redhat dot com>, Fariborz Jahanian <fjahanian at apple dot com>, "David S. Miller" <davem at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: 15 Oct 2003 21:55:12 -0700
- Subject: Re: [PATCH] - Use of powerpc 64bit instructions in 32bit ABI
- References: <200310160224.h9G2Oig29066@makai.watson.ibm.com>
David Edelsohn <email@example.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
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
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.