This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Problem when defining new mips insns
- From: Roger Sayle <roger at eyesopen dot com>
- To: Pontus Lidman <pontus at lysator dot liu dot se>
- Cc: gcc at gcc dot gnu dot org
- Date: Thu, 21 Oct 2004 19:56:09 -0600 (MDT)
- Subject: Re: Problem when defining new mips insns
On 21 Oct 2004, Pontus Lidman wrote:
> I'm trying to define some new instructions for handling TImode scalars
> on a mips r5900 cpu, and I encountered a problem I can't seem to
> understand properly or solve.
>
> The following program:
> long fun (double a) { return -a; }
>
> produces this result:
>
> ../../test/fix2.c: In function 'fun':
> ../../test/fix2.c:4: error: unrecognizable insn:
> (insn 14 13 15 0 ../../test/fix2.c:2 (set (reg:TI 186)
> (ashift:TI (reg:TI 187)
> (const_int 63 [0x3f]))) -1 (insn_list:REG_DEP_TRUE 13
> (nil))
> (expr_list:REG_DEAD (reg:TI 187)
> (expr_list:REG_EQUAL (const_int -9223372036854775808
> [0x8000000000000000])
> (nil))))
> ../../test/fix2.c:4: internal compiler error: in extract_insn, at
> recog.c:2034
>
> The cpu doesn't have shift instructions for TImode scalars, so I have
> defined library functions __ashrti3, __ashlti3. I have verified that
> these can be generated by the compiler in other test cases.
>
> What I'm wondering is, why and where is the above unrecognizable insn
> generated? I had expected a call to one of my library functions to be
> generated.
My guess is that the problem might be caused by not defining instructions
to load constants into TImode registers. By introducing TImode, the GCC
middle-end now realizes that it can implement IEEE floating point negation
by just flipping the sign bit, i.e. by doing an XOR in TImode, presumably
because sizeof(TImode) == sizeof(double). Hence the middle-end, tries to
expand "nega = (TImode)a ^ 0x8000000000000000". It looks like the RTL
expanders are unable to load this constant into a TImode register
directly, and instead try to generate this constant via "1 << 63".
I hope this provides enough of a clue to proceed from here.
Perhaps LEGITIMATE_CONSTANT_P or force_const_mem?
Roger
--