patches/gcc/3.4.3/pr16201-fix.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Jul 28 21:34:41 2007 +0000 (2007-07-28)
changeset 301 2be7232a73ac
permissions -rw-r--r--
Bump version to 0.2.2.
     1 See http://gcc.gnu.org/PR16201
     2 
     3 Should fix "bad immediate value for offset" errors for several flavors of arm, e.g.
     4 
     5 /tmp/ccmdoQyg.s: Assembler messages:
     6 /tmp/ccmdoQyg.s:6235: Error: bad immediate value for offset (4096)
     7 make[2]: *** [crosstool-0.32/build/arm-xscale-linux-gnu/gcc-3.4.3-glibc-2.3.3/build-glibc/locale/ld-collate.o] Error 1
     8 
     9 /tmp/cc0c7qop.s: Assembler messages:
    10 /tmp/cc0c7qop.s:6234: Error: bad immediate value for offset (4104)
    11 make[2]: *** [crosstool-0.32/build/armv5b-softfloat-linux/gcc-3.4.3-glibc-2.3.3/build-glibc/locale/ld-collate.o] Error 1
    12 
    13 
    14 CVSROOT:        /cvs/gcc
    15 Module name:    gcc
    16 Branch:         gcc-3_4-branch
    17 Changes by:     rearnsha@gcc.gnu.org    2005-02-01 15:07:05
    18 
    19 Modified files:
    20         gcc            : ChangeLog 
    21         gcc/config/arm : arm-protos.h arm.c 
    22 
    23 Log message:
    24         PR target/16201
    25         * arm.c (arm_eliminable_register): New function.
    26         (adjacent_mem_locations): Don't allow eliminable registers.  Use
    27         HOST_WIDE_INT for address offsets.
    28         * arm-protos.h (arm_eliminable_register): Add prototype.
    29 
    30 Patches:
    31 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.790&r2=2.2326.2.791
    32 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/arm/arm-protos.h.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.61&r2=1.61.4.1
    33 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/arm/arm.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.317.4.8&r2=1.317.4.9
    34 
    35 ===================================================================
    36 RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v
    37 retrieving revision 1.61
    38 retrieving revision 1.61.4.1
    39 diff -u -r1.61 -r1.61.4.1
    40 --- gcc/gcc/config/arm/arm-protos.h	2003/11/20 11:44:18	1.61
    41 +++ gcc/gcc/config/arm/arm-protos.h	2005/02/01 15:07:02	1.61.4.1
    42 @@ -1,5 +1,6 @@
    43  /* Prototypes for exported functions defined in arm.c and pe.c
    44 -   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    45 +   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005
    46 +   Free Software Foundation, Inc.
    47     Contributed by Richard Earnshaw (rearnsha@arm.com)
    48     Minor hacks by Nick Clifton (nickc@cygnus.com)
    49  
    50 @@ -138,6 +139,7 @@
    51  extern int arm_is_longcall_p (rtx, int, int);
    52  extern int    arm_emit_vector_const (FILE *, rtx);
    53  extern const char * arm_output_load_gr (rtx *);
    54 +extern int arm_eliminable_register (rtx);
    55  
    56  #if defined TREE_CODE
    57  extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
    58 ===================================================================
    59 RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
    60 retrieving revision 1.317.4.8
    61 retrieving revision 1.317.4.9
    62 diff -u -r1.317.4.8 -r1.317.4.9
    63 --- gcc/gcc/config/arm/arm.c	2004/04/29 19:52:41	1.317.4.8
    64 +++ gcc/gcc/config/arm/arm.c	2005/02/01 15:07:02	1.317.4.9
    65 @@ -1,6 +1,6 @@
    66  /* Output routines for GCC for ARM.
    67     Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
    68 -   2002, 2003, 2004  Free Software Foundation, Inc.
    69 +   2002, 2003, 2004, 2005  Free Software Foundation, Inc.
    70     Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    71     and Martin Simmons (@harleqn.co.uk).
    72     More major hacks by Richard Earnshaw (rearnsha@arm.com).
    73 @@ -4056,6 +4056,16 @@
    74  	  && INTVAL (op) < 64);
    75  }
    76  
    77 +/* Return true if X is a register that will be eliminated later on.  */
    78 +int
    79 +arm_eliminable_register (rtx x)
    80 +{
    81 +  return REG_P (x) && (REGNO (x) == FRAME_POINTER_REGNUM
    82 +		       || REGNO (x) == ARG_POINTER_REGNUM
    83 +		       || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
    84 +			   && REGNO (x) <= LAST_VIRTUAL_REGISTER));
    85 +}
    86 +
    87  /* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
    88     Use by the Cirrus Maverick code which has to workaround
    89     a hardware bug triggered by such instructions.  */
    90 @@ -4569,33 +4579,42 @@
    91  	  || (GET_CODE (XEXP (b, 0)) == PLUS
    92  	      && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
    93      {
    94 -      int val0 = 0, val1 = 0;
    95 -      int reg0, reg1;
    96 -  
    97 +      HOST_WIDE_INT val0 = 0, val1 = 0;
    98 +      rtx reg0, reg1;
    99 +      int val_diff;
   100 +
   101        if (GET_CODE (XEXP (a, 0)) == PLUS)
   102          {
   103 -	  reg0 = REGNO  (XEXP (XEXP (a, 0), 0));
   104 +	  reg0 = XEXP (XEXP (a, 0), 0);
   105  	  val0 = INTVAL (XEXP (XEXP (a, 0), 1));
   106          }
   107        else
   108 -	reg0 = REGNO (XEXP (a, 0));
   109 +	reg0 = XEXP (a, 0);
   110  
   111        if (GET_CODE (XEXP (b, 0)) == PLUS)
   112          {
   113 -	  reg1 = REGNO  (XEXP (XEXP (b, 0), 0));
   114 +	  reg1 = XEXP (XEXP (b, 0), 0);
   115  	  val1 = INTVAL (XEXP (XEXP (b, 0), 1));
   116          }
   117        else
   118 -	reg1 = REGNO (XEXP (b, 0));
   119 +	reg1 = XEXP (b, 0);
   120  
   121        /* Don't accept any offset that will require multiple
   122  	 instructions to handle, since this would cause the
   123  	 arith_adjacentmem pattern to output an overlong sequence.  */
   124        if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
   125  	return 0;
   126 -      
   127 -      return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
   128 +
   129 +      /* Don't allow an eliminable register: register elimination can make
   130 +	 the offset too large.  */
   131 +      if (arm_eliminable_register (reg0))
   132 +	return 0;
   133 +
   134 +      val_diff = val1 - val0;
   135 +      return ((REGNO (reg0) == REGNO (reg1))
   136 +	      && (val_diff == 4 || val_diff == -4));
   137      }
   138 +
   139    return 0;
   140  }
   141  
   142 @@ -7301,7 +7320,6 @@
   143    return "";
   144  }
   145  
   146 -
   147  /* Output a move from arm registers to an fpa registers.
   148     OPERANDS[0] is an fpa register.
   149     OPERANDS[1] is the first registers of an arm register pair.  */