This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: mips_legitimate_address_p problem
- To: Aldy Hernandez <aldyh at redhat dot com>
- Subject: Re: mips_legitimate_address_p problem
- From: Graham Stott <grahams at redhat dot com>
- Date: Thu, 09 Aug 2001 08:11:20 +0100
- Cc: gcc patches <gcc-patches at gcc dot gnu dot org>
- References: <997288879.30289.8.camel@culebra.cygnus.com>
Aldy,
Aldy Hernandez wrote:
>
> hi y'all.
>
> 960402-1.c is failing for 64bit mips.
>
> >
> > This insn:
> >
> > (insn 15 40 37 (set (reg:DI 4 a0 [84])
> > (plus:DI (reg/v:DI 4 a0 [82])
> > (const_int 2147483648 [0x80000000]))) 339 {leadi} (nil)
> > (nil))
> >
> > is being matched by:
> >
> > (define_insn "leadi"
> > [(set (match_operand:DI 0 "register_operand" "=d")
> > (match_operand:DI 1 "address_operand" "p"))]
> > "Pmode == DImode"
> > "la %0,%a1"
> > [(set_attr "type" "arith")
> > (set_attr "mode" "DI")
> > (set_attr "length" "40")])
> >
> > because legitimize address matches (plus (reg a0) (const 0x80000000).
> >
> > eventually, we generate:
> >
> > la $4,0x80000000($4)
> >
> > which is a macro and gets expanded by the assembler into:
> >
> > lui at,0x8000
> > daddu a0,at,a0
> >
> > however, "lui" on 64bit mips loads 0x8000 into the upper half and sign
> > extends onto bits 32-63. (32bit mips does not sign extend). so, we end
> > up with:
> >
> > AT <-- 0xffffffff80000000
> >
> > consequently, insn 15 calculates the wrong result.
>
> > debugging, i found the following in mips_legitimate_address_p():
> >
> > /* When assembling for machines with 64 bit registers,
> > the assembler will not sign-extend the constant "foo"
> > in "la x, foo(x)" */
> > && (!TARGET_64BIT || (code1 == CONST_INT && INTVAL (xplus1) > 0))
> >
> machines with 64 bit registers WILL sign-extend the constant foo. i've
> verified with the mips64 specs.
>
> the following patch fixes the problem. tested on 64 and 32 bit mips.
>
> ok to install?
>
> 2001-08-07 Aldy Hernandez <aldyh@redhat.com>
>
> * config/mips/mips.c (mips_legitimate_address_p): Limit "la" addresses.
>
> Index: mips.c
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/config/mips/mips.c,v
> retrieving revision 1.134
> diff -c -p -r1.134 mips.c
> *** mips.c 2001/08/08 15:40:57 1.134
> --- mips.c 2001/08/08 16:38:38
> *************** mips_legitimate_address_p (mode, xinsn,
> *** 1364,1372 ****
> || code1 != CONST
> || GET_CODE (XEXP (xplus1, 0)) != MINUS)
> /* When assembling for machines with 64 bit registers,
> ! the assembler will not sign-extend the constant "foo"
> ! in "la x, foo(x)" */
> ! && (!TARGET_64BIT || (code1 == CONST_INT && INTVAL (xplus1) > 0))
> && !TARGET_MIPS16)
> return 1;
> }
> --- 1364,1375 ----
> || code1 != CONST
> || GET_CODE (XEXP (xplus1, 0)) != MINUS)
> /* When assembling for machines with 64 bit registers,
> ! the assembler will sign-extend the constant "foo"
> ! in "la x, foo(x)" yielding the wrong result for:
> ! (set (blah:DI) (plus x y)). */
> ! && (!TARGET_64BIT
> ! || trunc_int_for_mode (INTVAL (xplus1),
> ! SImode) == INTVAL (xplus1))
> && !TARGET_MIPS16)
> return 1;
> }
xplus1 is not always a CONST_INT so you need to check code1 is a CONST_INT
before trying to do the test. This shows up of you build with enable-checking
Graham