This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
mips_legitimate_address_p problem
- To: gcc patches <gcc-patches at gcc dot gnu dot org>
- Subject: mips_legitimate_address_p problem
- From: Aldy Hernandez <aldyh at redhat dot com>
- Date: 08 Aug 2001 19:41:19 +0300
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;
}