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]

mips_legitimate_address_p problem


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


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