This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: 64-bit powerpc compare with constant problem
- To: dje at watson dot ibm dot com
- Subject: Re: 64-bit powerpc compare with constant problem
- From: Geoff Keating <geoffk at cygnus dot com>
- Date: Sat, 12 Feb 2000 21:41:37 -0800
- CC: ben at eecg dot toronto dot edu, gcc-bugs at gcc dot gnu dot org
- References: <200002130357.WAA24710@mal-ach.watson.ibm.com>
> cc: ben@eecg.toronto.edu, gcc-bugs@gcc.gnu.org
> Date: Sat, 12 Feb 2000 22:57:34 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> Sigh. This is proving much more difficult to get right than I
> originally had expected. PowerPC can perform the logical OR and logical
> XOR of any 32-bit quantity using two instructions with immediate operands,
> operating on a 32-bit register in 32-bit mode and a 64-bit register in
> 64-bit mode. I am running into the problem that GCC carries around
> integer values in the host platform's widest signed integer.
>
> For the two DImode logical OR/XOR patterns, I want to accept any
> 32-bit unsigned constant. One important use of this is materializing
> 64-bit constants in a register. Given GCC's limited CONST_INT, I cannot
> see how to accept any 32-bit value on a 32-bit host without GCC equating
> 32-bit constants in which the high bit is set with a signed 32-bit
> constant. GCC treats the operation as if it would affect the upper 32
> bits of a 64-bit word.
That's because the operation does affect the upper 32 bits of a 64-bit
word. In RTL, with HOST_WIDE_INT is 32 bits, in TARGET_POWERPC32,
(set (reg:DI 3) (xor:DI (reg:DI 3) (const_int 0xfffffffe)))
is intended to be equivalent to the ppc opcodes (when WORDS_BIGENDIAN)
not r3,r3
xoris r4,r4,0xffff
xori r4,r4,0xfffe
which are in RTL:
(set (reg:DI 3) (xor:DI (reg:DI 3) (const_double 0xffffffff 0)))
(set (reg:DI 3) (xor:DI (reg:DI 3) (const_double 0 0xffff0000)))
(set (reg:DI 3) (xor:DI (reg:DI 3) (const_int 0x0000fffe)))
note that there is no such RTL as (const_double 0xffffffff
0xfffffffe); it's invalid, and GEN_INT will not make it.
(there is only one correct RTL form for each of these insns in
DImode---of course, really these should be SImode operating on
two registers.)
Now, I know that there are places in the compiler that don't
understand this, and will happily decide that
(add:DI (const_int 0x40000000) (const_int 0x40000000))
is equivalent to
(const_int 0x80000000)
but these places are wrong and should be fixed.
--
- Geoffrey Keating <geoffk@cygnus.com>