This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


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

Re: 64-bit powerpc compare with constant problem


> 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>

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