This is the mail archive of the gcc-patches@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: mips_legitimate_address_p problem


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


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