patches/gcc/2.95.3/arm-linux.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Feb 24 11:00:05 2007 +0000 (2007-02-24)
changeset 1 eeea35fbf182
permissions -rw-r--r--
Add the full crosstool-NG sources to the new repository of its own.
You might just say: 'Yeah! crosstool-NG's got its own repo!".
Unfortunately, that's because the previous repo got damaged beyond repair and I had no backup.
That means I'm putting backups in place in the afternoon.
That also means we've lost history... :-(
     1 --------- snip -------
     2 Downloaded from ftp://ftp.linux.org.uk/pub/armlinux/toolchain/src-2.95.3/gcc-2.95.3.diff.bz2
     3 Not sure what it fixes, but this appears to be The Patch used with gcc-2.95.3 on arm.
     4 --------- snip -------
     5 
     6 diff -urN gcc-2.95.3-orig/gcc/config/arm/arm.c gcc-2.95.3/gcc/config/arm/arm.c
     7 --- gcc-2.95.3-orig/gcc/config/arm/arm.c	Thu Jan 25 15:03:24 2001
     8 +++ gcc-2.95.3/gcc/config/arm/arm.c	Fri Jul 20 19:39:11 2001
     9 @@ -1529,27 +1529,34 @@
    10        return gen_rtx_PLUS (Pmode, base, offset);
    11      }
    12    else if (GET_CODE (orig) == LABEL_REF)
    13 -    current_function_uses_pic_offset_table = 1;
    14 -
    15 -  return orig;
    16 -}
    17 +    {
    18 +      current_function_uses_pic_offset_table = 1;
    19  
    20 -static rtx pic_rtx;
    21 +      if (NEED_PLT_GOT)
    22 +	{
    23 +	  rtx pic_ref, address = gen_reg_rtx (Pmode);
    24 +	  
    25 +	  emit_insn (gen_pic_load_addr (address, orig));
    26 +	  pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
    27 +				  address);
    28 +	  emit_move_insn (address, pic_ref);
    29 +	  return address;
    30 +	}
    31 +    }
    32  
    33 -int
    34 -is_pic(x)
    35 -     rtx x;
    36 -{
    37 -  if (x == pic_rtx)
    38 -    return 1;
    39 -  return 0;
    40 +  return orig;
    41  }
    42  
    43 +/* Generate code to load the PIC register.  PROLOGUE is true if
    44 +   called from arm_expand_prologue (in which case we want the 
    45 +   generated insns at the start of the function);  false if called
    46 +   by an exception receiver that needs the PIC register reloaded
    47 +   (in which case the insns are just dumped at the current location).  */
    48  void
    49 -arm_finalize_pic ()
    50 +arm_finalize_pic (int prologue)
    51  {
    52  #ifndef AOF_ASSEMBLER
    53 -  rtx l1, pic_tmp, pic_tmp2, seq;
    54 +  rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx;
    55    rtx global_offset_table;
    56  
    57    if (current_function_uses_pic_offset_table == 0)
    58 @@ -1578,7 +1585,10 @@
    59  
    60    seq = gen_sequence ();
    61    end_sequence ();
    62 -  emit_insn_after (seq, get_insns ());
    63 +  if (prologue)
    64 +    emit_insn_after (seq, get_insns ());
    65 +  else
    66 +    emit_insn (seq);
    67  
    68    /* Need to emit this whether or not we obey regdecls,
    69       since setjmp/longjmp can cause life info to screw up.  */
    70 @@ -5327,7 +5337,13 @@
    71    if (frame_pointer_needed)
    72      live_regs += 4;
    73  
    74 -  if (live_regs)
    75 +  if (live_regs == 1 && regs_ever_live[LR_REGNUM]
    76 +      && ! lr_save_eliminated && ! really_return)
    77 +    {
    78 +      output_asm_insn (reverse ? "ldr%?%D0\t%|lr, [%|sp}, #4"
    79 +      		       : "ldr%?%d0\t%|lr, [%|sp], #4", &operand);
    80 +    }
    81 +  else if (live_regs)
    82      {
    83        if (lr_save_eliminated || ! regs_ever_live[14])
    84          live_regs++;
    85 @@ -5446,7 +5462,7 @@
    86    rtx           x;
    87  
    88    length = strlen (name);
    89 -  alignlength = (length + 1) + 3 & ~3;
    90 +  alignlength = ((length + 1) + 3) & ~3;
    91    
    92    ASM_OUTPUT_ASCII (stream, name, length + 1);
    93    ASM_OUTPUT_ALIGN (stream, 2);
    94 @@ -5838,6 +5854,9 @@
    95    int store_arg_regs = 0;
    96    int volatile_func = (optimize > 0
    97  		       && TREE_THIS_VOLATILE (current_function_decl));
    98 +  rtx ip_rtx;
    99 +  int fp_offset = 0;
   100 +  rtx insn;
   101  
   102    /* Naked functions don't have prologues.  */
   103    if (arm_naked_function_p (current_function_decl))
   104 @@ -5859,11 +5878,59 @@
   105  	live_regs_mask |= 0x4000;
   106      }
   107  
   108 +  ip_rtx = gen_rtx_REG (SImode, IP_REGNUM);
   109 +
   110    if (frame_pointer_needed)
   111      {
   112 +      if (current_function_needs_context)
   113 +	{
   114 +	  /* The Static chain register is the same as the IP register
   115 +	     used as a scratch register during stack frame creation.
   116 +	     To get around this need to find somewhere to store IP
   117 +	     whilst the frame is being created.  We try the following
   118 +	     places in order:
   119 +	     
   120 +	       1. An unused argument register.
   121 +	       2. A slot on the stack above the frame.  (This only
   122 +	          works if the function is not a varargs function).
   123 +		  
   124 +	     If neither of these places is available, we abort (for now).  */
   125 +	  if (regs_ever_live[3] == 0)
   126 +	    {
   127 +	      insn = gen_rtx_REG (SImode, 3);
   128 +	      insn = gen_rtx_SET (SImode, insn, ip_rtx);
   129 +	      insn = emit_insn (insn);
   130 +	      RTX_FRAME_RELATED_P (insn) = 1;	  
   131 +	    }
   132 +	  else if (current_function_pretend_args_size == 0)
   133 +	    {
   134 +	      insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
   135 +	      insn = gen_rtx_MEM (SImode, insn);
   136 +	      insn = gen_rtx_SET (VOIDmode, insn, ip_rtx);
   137 +	      insn = emit_insn (insn);
   138 +	      RTX_FRAME_RELATED_P (insn) = 1;
   139 +	      fp_offset = 4;
   140 +	    }
   141 +	  else
   142 +	    /* FIXME - the way to handle this situation is to allow
   143 +	       the pretend args to be dumped onto the stack, then
   144 +	       reuse r3 to save IP.  This would involve moving the
   145 +	       copying os SP into IP until after the pretend args
   146 +	       have been dumped, but this is not too hard.  */
   147 +	    error ("Unable to find a temporary location for static chanin register");
   148 +	}
   149 +
   150        live_regs_mask |= 0xD800;
   151 -      emit_insn (gen_movsi (gen_rtx_REG (SImode, 12),
   152 -			    stack_pointer_rtx));
   153 +      if (fp_offset)
   154 +	{
   155 +	  insn = gen_rtx_PLUS (SImode, stack_pointer_rtx, GEN_INT (fp_offset));
   156 +	  insn = gen_rtx_SET  (SImode, ip_rtx, insn);
   157 +	}
   158 +      else
   159 +	insn = gen_movsi (ip_rtx, stack_pointer_rtx);
   160 +      
   161 +       insn = emit_insn (insn);
   162 +       RTX_FRAME_RELATED_P (insn) = 1;
   163      }
   164  
   165    if (current_function_pretend_args_size)
   166 @@ -5927,9 +5994,31 @@
   167      }
   168  
   169    if (frame_pointer_needed)
   170 -    emit_insn (gen_addsi3 (hard_frame_pointer_rtx, gen_rtx_REG (SImode, 12),
   171 -			   (GEN_INT
   172 -			    (-(4 + current_function_pretend_args_size)))));
   173 +    {
   174 +      insn = GEN_INT (-(4 + current_function_pretend_args_size + fp_offset));
   175 +      insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ip_rtx, insn));
   176 +      RTX_FRAME_RELATED_P (insn) = 1;
   177 +      
   178 +      if (current_function_needs_context)
   179 +	{
   180 +	  /* Recover the static chain register.  */
   181 +	  if (regs_ever_live [3] == 0)
   182 +	    {
   183 +	      insn = gen_rtx_REG (SImode, 3);
   184 +	      insn = gen_rtx_SET (SImode, ip_rtx, insn);
   185 +	      insn = emit_insn (insn);
   186 +	      RTX_FRAME_RELATED_P (insn) = 1;	  
   187 +	    }
   188 +	  else /* if (current_function_pretend_args_size == 0) */
   189 +	    {
   190 +	      insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx, GEN_INT (4));
   191 +	      insn = gen_rtx_MEM (SImode, insn);
   192 +	      insn = gen_rtx_SET (SImode, ip_rtx, insn);
   193 +	      insn = emit_insn (insn);
   194 +	      RTX_FRAME_RELATED_P (insn) = 1;	  
   195 +	    }
   196 +	}
   197 +    }
   198  
   199    if (amount != const0_rtx)
   200      {
   201 diff -urN gcc-2.95.3-orig/gcc/config/arm/arm.h gcc-2.95.3/gcc/config/arm/arm.h
   202 --- gcc-2.95.3-orig/gcc/config/arm/arm.h	Thu Jan 25 15:03:26 2001
   203 +++ gcc-2.95.3/gcc/config/arm/arm.h	Fri Jul 20 19:39:11 2001
   204 @@ -601,14 +601,20 @@
   205    (TREE_CODE (EXP) == STRING_CST        \
   206     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
   207  
   208 +#ifndef STRUCTURE_SIZE_BOUNDARY
   209  /* Every structures size must be a multiple of 32 bits.  */
   210  /* This is for compatibility with ARMCC.  ARM SDT Reference Manual
   211     (ARM DUI 0020D) page 2-20 says "Structures are aligned on word
   212     boundaries".  */
   213 -#ifndef STRUCTURE_SIZE_BOUNDARY
   214 -#define STRUCTURE_SIZE_BOUNDARY 32
   215 +/* Setting this to 32 produces more efficient code, but the value set in previous
   216 +   versions of this toolchain was 8, which produces more compact structures. The
   217 +   command line option -mstructure_size_boundary=<n> can be used to change this
   218 +   value.  */
   219 +#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
   220  #endif
   221  
   222 +extern int arm_structure_size_boundary;
   223 +
   224  /* Used when parsing command line option -mstructure_size_boundary.  */
   225  extern const char * structure_size_string;
   226  
   227 @@ -768,6 +774,9 @@
   228  /* Specify the registers used for certain standard purposes.
   229     The values of these macros are register numbers.  */
   230  
   231 +/* Register which holds return address from a subroutine call.  */
   232 +#define LR_REGNUM		14
   233 +
   234  /* Define this if the program counter is overloaded on a register.  */
   235  #define PC_REGNUM		15
   236  
   237 @@ -777,6 +786,9 @@
   238  /* Base register for access to local variables of the function.  */
   239  #define FRAME_POINTER_REGNUM	25
   240  
   241 +/* Scratch register - used in all kinds of places, eg trampolines.  */
   242 +#define IP_REGNUM		12
   243 +
   244  /* Define this to be where the real frame pointer is if it is not possible to
   245     work out the offset between the frame pointer and the automatic variables
   246     until after register allocation has taken place.  FRAME_POINTER_REGNUM
   247 @@ -798,7 +810,7 @@
   248  /* The native (Norcroft) Pascal compiler for the ARM passes the static chain
   249     as an invisible last argument (possible since varargs don't exist in
   250     Pascal), so the following is not true.  */
   251 -#define STATIC_CHAIN_REGNUM	8
   252 +#define STATIC_CHAIN_REGNUM	12
   253  
   254  /* Register in which address to store a structure value
   255     is passed to a function.  */
   256 @@ -1248,7 +1260,12 @@
   257  {									\
   258    int volatile_func = arm_volatile_func ();				\
   259    if ((FROM) == ARG_POINTER_REGNUM && (TO) == HARD_FRAME_POINTER_REGNUM)\
   260 -    (OFFSET) = 0;							\
   261 +    {                                                                   \
   262 +      if (! current_function_needs_context || ! frame_pointer_needed)   \
   263 +        (OFFSET) = 0;                                                   \
   264 +      else                                                              \
   265 +        (OFFSET) = 4;                                                   \
   266 +    }                                                                   \
   267    else if ((FROM) == FRAME_POINTER_REGNUM				\
   268  	   && (TO) == STACK_POINTER_REGNUM)				\
   269      (OFFSET) = (current_function_outgoing_args_size			\
   270 @@ -1379,8 +1396,10 @@
   271  
   272     On the ARM, allow any integer (invalid ones are removed later by insn
   273     patterns), nice doubles and symbol_refs which refer to the function's
   274 -   constant pool XXX.  */
   275 -#define LEGITIMATE_CONSTANT_P(X)	(! label_mentioned_p (X))
   276 +   constant pool XXX.
   277 +
   278 +   When generating PIC code, allow anything.  */
   279 +#define LEGITIMATE_CONSTANT_P(X)	(flag_pic || ! label_mentioned_p (X))
   280  
   281  /* Symbols in the text segment can be accessed without indirecting via the
   282     constant pool; it may take an extra binary operation, but this is still
   283 @@ -1496,9 +1515,8 @@
   284  	      && INTVAL (op) <= 31)					\
   285  	    goto LABEL;							\
   286          }								\
   287 -      /* NASTY: Since this limits the addressing of unsigned byte loads */      \
   288        range = ((MODE) == HImode || (MODE) == QImode)                    \
   289 -              ? (arm_arch4 ? 256 : 4095) : 4096;                        \
   290 +              ? (((MODE) == HImode && arm_arch4) ? 256 : 4095) : 4096;  \
   291        if (code == CONST_INT && INTVAL (INDEX) < range			\
   292  	  && INTVAL (INDEX) > -range)  	      				\
   293          goto LABEL;							\
   294 @@ -1812,14 +1830,15 @@
   295     data addresses in memory.  */
   296  #define PIC_OFFSET_TABLE_REGNUM arm_pic_register
   297  
   298 -#define FINALIZE_PIC arm_finalize_pic ()
   299 +#define FINALIZE_PIC arm_finalize_pic (1)
   300  
   301 -/* We can't directly access anything that contains a symbol,
   302 +/* We can't directly access anything that contains a symbol or label,
   303     nor can we indirect via the constant pool.  */
   304  #define LEGITIMATE_PIC_OPERAND_P(X)				\
   305 -	(! symbol_mentioned_p (X)				\
   306 +	(! symbol_mentioned_p (X) && ! label_mentioned_p (X)	\
   307  	 && (! CONSTANT_POOL_ADDRESS_P (X)			\
   308 -	     || ! symbol_mentioned_p (get_pool_constant (X))))
   309 +	     || (! symbol_mentioned_p (get_pool_constant (X)))  \
   310 +		&& (! label_mentioned_p (get_pool_constant (X)))))
   311   
   312  /* We need to know when we are making a constant pool; this determines
   313     whether data needs to be in the GOT or can be referenced via a GOT
   314 @@ -2046,17 +2065,9 @@
   315    else output_addr_const(STREAM, X);					\
   316  }
   317  
   318 -/* Handles PIC addr specially */
   319  #define OUTPUT_INT_ADDR_CONST(STREAM,X) \
   320    {									\
   321 -    if (flag_pic && GET_CODE(X) == CONST && is_pic(X))			\
   322 -      {									\
   323 -	output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 0), 0));	\
   324 -	fputs(" - (", STREAM);						\
   325 -	output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 1), 0));	\
   326 -	fputs(")", STREAM);						\
   327 -      }									\
   328 -    else output_addr_const(STREAM, X);					\
   329 +    output_addr_const(STREAM, X);					\
   330  									\
   331      /* Mark symbols as position independent.  We only do this in the	\
   332        .text segment, not in the .data segment. */			\
   333 @@ -2170,8 +2181,7 @@
   334  int    arm_return_in_memory PROTO ((Tree));
   335  int    legitimate_pic_operand_p PROTO ((Rtx));
   336  Rtx    legitimize_pic_address PROTO ((Rtx, Mmode, Rtx));
   337 -int    is_pic PROTO ((Rtx));
   338 -void   arm_finalize_pic PROTO ((void));
   339 +void   arm_finalize_pic PROTO ((int));
   340  int    arm_rtx_costs RTX_CODE_PROTO ((Rtx, Rcode));
   341  int    arm_adjust_cost PROTO ((Rtx, Rtx, Rtx, int));
   342  int    const_double_rtx_ok_for_fpu PROTO ((Rtx));
   343 diff -urN gcc-2.95.3-orig/gcc/config/arm/arm.md gcc-2.95.3/gcc/config/arm/arm.md
   344 --- gcc-2.95.3-orig/gcc/config/arm/arm.md	Thu Jan 25 15:03:27 2001
   345 +++ gcc-2.95.3/gcc/config/arm/arm.md	Fri Jul 20 19:39:11 2001
   346 @@ -2629,7 +2629,8 @@
   347  			   : preserve_subexpressions_p ()));
   348        DONE;
   349      }
   350 -  if (CONSTANT_P (operands[1]) && flag_pic)
   351 +  if ((CONSTANT_P (operands[1]) || symbol_mentioned_p (operands[1])
   352 +        || label_mentioned_p (operands[1])) && flag_pic)
   353      operands[1] = legitimize_pic_address (operands[1], SImode,
   354  					  ((reload_in_progress
   355  					    || reload_completed)
   356 @@ -2721,6 +2722,15 @@
   357    return \"add%?\\t%0, %|pc, %0\";
   358  ")
   359  
   360 +(define_expand "builtin_setjmp_receiver"
   361 +  [(label_ref (match_operand 0 "" ""))]
   362 +  "flag_pic"
   363 +  "
   364 +{
   365 +  arm_finalize_pic (0);
   366 +  DONE;
   367 +}")
   368 +
   369  ;; If copying one reg to another we can set the condition codes according to
   370  ;; its value.  Such a move is common after a return from subroutine and the
   371  ;; result is being tested against zero.
   372 @@ -6184,15 +6194,20 @@
   373  	abort ();
   374        return \"\";
   375      }
   376 -  strcpy (pattern, \"stmfd\\t%m0!, {%1\");
   377 -  for (i = 1; i < XVECLEN (operands[2], 0); i++)
   378 +  if (XVECLEN (operands[2], 0) > 1)
   379      {
   380 -      strcat (pattern, \", %|\");
   381 -      strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
   382 +      strcpy (pattern, \"stmfd\\t%m0!, {%1\");
   383 +      for (i = 1; i < XVECLEN (operands[2], 0); i++)
   384 +        {
   385 +           strcat (pattern, \", %|\");
   386 +           strcat (pattern, reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i),
   387  					      0))]);
   388 +        }
   389 +      strcat (pattern, \"}\");
   390 +      output_asm_insn (pattern, operands);
   391      }
   392 -  strcat (pattern, \"}\");
   393 -  output_asm_insn (pattern, operands);
   394 +  else
   395 +    output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands);
   396    return \"\";
   397  }"
   398  [(set_attr "type" "store4")])
   399 diff -urN gcc-2.95.3-orig/gcc/config/arm/elf.h gcc-2.95.3/gcc/config/arm/elf.h
   400 --- gcc-2.95.3-orig/gcc/config/arm/elf.h	Mon May 31 10:21:53 1999
   401 +++ gcc-2.95.3/gcc/config/arm/elf.h	Fri Jul 20 19:39:11 2001
   402 @@ -167,15 +167,6 @@
   403  #define MULTILIB_DEFAULTS { "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork" }
   404  #endif
   405  
   406 -/* Setting this to 32 produces more efficient code, but the value set in previous
   407 -   versions of this toolchain was 8, which produces more compact structures. The
   408 -   command line option -mstructure_size_boundary=<n> can be used to change this
   409 -   value.  */
   410 -#undef  STRUCTURE_SIZE_BOUNDARY
   411 -#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
   412 -
   413 -extern int arm_structure_size_boundary;
   414 -
   415  /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
   416     is a valid machine specific attribute for DECL.
   417     The attributes in ATTRIBUTES have previously been assigned to DECL.  */
   418 diff -urN gcc-2.95.3-orig/gcc/config/arm/linux-gas.h gcc-2.95.3/gcc/config/arm/linux-gas.h
   419 --- gcc-2.95.3-orig/gcc/config/arm/linux-gas.h	Mon Feb 22 17:47:57 1999
   420 +++ gcc-2.95.3/gcc/config/arm/linux-gas.h	Fri Jul 20 19:39:11 2001
   421 @@ -1,6 +1,6 @@
   422  /* Definitions of target machine for GNU compiler.
   423     ARM Linux-based GNU systems version.
   424 -   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
   425 +   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
   426     Contributed by Russell King  <rmk92@ecs.soton.ac.uk>.
   427  
   428  This file is part of GNU CC.
   429 @@ -79,5 +79,7 @@
   430    register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
   431    register unsigned long _end __asm ("a2") = (unsigned long) (END);	\
   432    register unsigned long _flg __asm ("a3") = 0;				\
   433 -  __asm __volatile ("swi 0x9f0002");					\
   434 +  __asm __volatile ("swi 0x9f0002		@ sys_cacheflush"	\
   435 +		    : "=r" (_beg)					\
   436 +		    : "0" (_beg), "r" (_end), "r" (_flg));		\
   437  }
   438 diff -urN gcc-2.95.3-orig/gcc/config/arm/t-linux gcc-2.95.3/gcc/config/arm/t-linux
   439 --- gcc-2.95.3-orig/gcc/config/arm/t-linux	Fri Mar 26 16:30:20 1999
   440 +++ gcc-2.95.3/gcc/config/arm/t-linux	Fri Jul 20 20:46:19 2001
   441 @@ -1,6 +1,6 @@
   442  # Just for these, we omit the frame pointer since it makes such a big
   443  # difference.  It is then pointless adding debugging.
   444 -TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
   445 +TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC 
   446  LIBGCC2_DEBUG_CFLAGS = -g0
   447  
   448  # Don't build enquire
   449 diff -urN gcc-2.95.3-orig/gcc/final.c gcc-2.95.3/gcc/final.c
   450 --- gcc-2.95.3-orig/gcc/final.c	Mon Mar 12 13:07:59 2001
   451 +++ gcc-2.95.3/gcc/final.c	Fri Jul 20 19:39:11 2001
   452 @@ -3652,8 +3652,9 @@
   453  
   454        output_addr_const (file, XEXP (x, 0));
   455        fprintf (file, "-");
   456 -      if (GET_CODE (XEXP (x, 1)) == CONST_INT
   457 -	  && INTVAL (XEXP (x, 1)) < 0)
   458 +      if ((GET_CODE (XEXP (x, 1)) == CONST_INT
   459 +	   && INTVAL (XEXP (x, 1)) < 0)
   460 +	  || GET_CODE (XEXP (x, 1)) != CONST_INT)
   461  	{
   462  	  fprintf (file, ASM_OPEN_PAREN);
   463  	  output_addr_const (file, XEXP (x, 1));
   464 diff -urN gcc-2.95.3-orig/gcc/function.c gcc-2.95.3/gcc/function.c
   465 --- gcc-2.95.3-orig/gcc/function.c	Thu Jan 25 15:03:15 2001
   466 +++ gcc-2.95.3/gcc/function.c	Fri Jul 20 19:39:10 2001
   467 @@ -3053,6 +3053,105 @@
   468     extracted by usage MEM with narrower mode. */
   469  static rtx purge_addressof_replacements;
   470  
   471 +/* Return 1 if X and Y are identical-looking rtx's.
   472 +   This is the Lisp function EQUAL for rtx arguments.  */
   473 +
   474 +int
   475 +rtx_equal_for_addressof_p (x, y)
   476 +     rtx x, y;
   477 +{
   478 +  register int i;
   479 +  register int j;
   480 +  register enum rtx_code code;
   481 +  register char *fmt;
   482 +
   483 +  if (x == y)
   484 +    return 1;
   485 +  if (x == 0 || y == 0)
   486 +    return 0;
   487 +
   488 +  code = GET_CODE (x);
   489 +  /* Rtx's of different codes cannot be equal.  */
   490 +  if (code != GET_CODE (y))
   491 +    return 0;
   492 +
   493 +  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
   494 +     (REG:SI x) and (REG:HI x) are NOT equivalent. 
   495 +     But (MEM:SI x) and (MEM:HI x) are equivalent for our purposes.  */
   496 +
   497 +  if (code != MEM && (GET_MODE (x) != GET_MODE (y)))
   498 +    return 0;
   499 +
   500 +  /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively.  */
   501 +
   502 +  if (code == REG)
   503 +    return REGNO (x) == REGNO (y);
   504 +  else if (code == LABEL_REF)
   505 +    return XEXP (x, 0) == XEXP (y, 0);
   506 +  else if (code == SYMBOL_REF)
   507 +    return XSTR (x, 0) == XSTR (y, 0);
   508 +  else if (code == SCRATCH || code == CONST_DOUBLE)
   509 +    return 0;
   510 +
   511 +  /* Compare the elements.  If any pair of corresponding elements
   512 +     fail to match, return 0 for the whole things.  */
   513 +
   514 +  fmt = GET_RTX_FORMAT (code);
   515 +  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
   516 +    {
   517 +      switch (fmt[i])
   518 +	{
   519 +	case 'w':
   520 +	  if (XWINT (x, i) != XWINT (y, i))
   521 +	    return 0;
   522 +	  break;
   523 +
   524 +	case 'n':
   525 +	case 'i':
   526 +	  if (XINT (x, i) != XINT (y, i))
   527 +	    return 0;
   528 +	  break;
   529 +
   530 +	case 'V':
   531 +	case 'E':
   532 +	  /* Two vectors must have the same length.  */
   533 +	  if (XVECLEN (x, i) != XVECLEN (y, i))
   534 +	    return 0;
   535 +
   536 +	  /* And the corresponding elements must match.  */
   537 +	  for (j = 0; j < XVECLEN (x, i); j++)
   538 +	    if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
   539 +	      return 0;
   540 +	  break;
   541 +
   542 +	case 'e':
   543 +	  if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
   544 +	    return 0;
   545 +	  break;
   546 +
   547 +	case 'S':
   548 +	case 's':
   549 +	  if (strcmp (XSTR (x, i), XSTR (y, i)))
   550 +	    return 0;
   551 +	  break;
   552 +
   553 +	case 'u':
   554 +	  /* These are just backpointers, so they don't matter.  */
   555 +	  break;
   556 +
   557 +	case '0':
   558 +	  break;
   559 +
   560 +	  /* It is believed that rtx's at this level will never
   561 +	     contain anything but integers and other rtx's,
   562 +	     except for within LABEL_REFs and SYMBOL_REFs.  */
   563 +	default:
   564 +	  abort ();
   565 +	}
   566 +    }
   567 +  return 1;
   568 +}
   569 +
   570  /* Helper function for purge_addressof.  See if the rtx expression at *LOC
   571     in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
   572     the stack.  */
   573 @@ -3133,7 +3232,7 @@
   574  	      for (tem = purge_bitfield_addressof_replacements;
   575  		   tem != NULL_RTX;
   576  		   tem = XEXP (XEXP (tem, 1), 1))
   577 -		if (rtx_equal_p (x, XEXP (tem, 0)))
   578 +		if (rtx_equal_for_addressof_p (x, XEXP (tem, 0)))
   579  		  {
   580  		    *loc = XEXP (XEXP (tem, 1), 0);
   581  		    return;
   582 @@ -3143,7 +3242,7 @@
   583  	      for (tem = purge_addressof_replacements;
   584  		   tem != NULL_RTX;
   585  		   tem = XEXP (XEXP (tem, 1), 1))
   586 -		if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
   587 +		if (rtx_equal_for_addressof_p (XEXP (x, 0), XEXP (tem, 0)))
   588  		  {
   589  		    rtx z = XEXP (XEXP (tem, 1), 0);
   590  
   591 diff -urN gcc-2.95.3-orig/gcc/jump.c gcc-2.95.3/gcc/jump.c
   592 --- gcc-2.95.3-orig/gcc/jump.c	Thu Oct 21 08:24:03 1999
   593 +++ gcc-2.95.3/gcc/jump.c	Fri Jul 20 19:39:10 2001
   594 @@ -115,7 +115,7 @@
   595  static rtx delete_unreferenced_labels	PROTO((rtx));
   596  static void delete_noop_moves		PROTO((rtx));
   597  static int calculate_can_reach_end	PROTO((rtx, int, int));
   598 -static int duplicate_loop_exit_test	PROTO((rtx));
   599 +static int duplicate_loop_exit_test	PROTO((rtx, int));
   600  static void find_cross_jump		PROTO((rtx, rtx, int, rtx *, rtx *));
   601  static void do_cross_jump		PROTO((rtx, rtx, rtx));
   602  static int jump_back_p			PROTO((rtx, rtx));
   603 @@ -338,7 +338,7 @@
   604  	      && simplejump_p (temp1))
   605  	    {
   606  	      temp = PREV_INSN (insn);
   607 -	      if (duplicate_loop_exit_test (insn))
   608 +	      if (duplicate_loop_exit_test (insn, after_regscan))
   609  		{
   610  		  changed = 1;
   611  		  next = NEXT_INSN (temp);
   612 @@ -2548,8 +2548,9 @@
   613     values of regno_first_uid and regno_last_uid.  */
   614  
   615  static int
   616 -duplicate_loop_exit_test (loop_start)
   617 +duplicate_loop_exit_test (loop_start, after_regscan)
   618       rtx loop_start;
   619 +     int after_regscan;
   620  {
   621    rtx insn, set, reg, p, link;
   622    rtx copy = 0, first_copy = 0;
   623 @@ -2662,6 +2663,9 @@
   624  	    reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg));
   625  	  }
   626        }
   627 +
   628 +  if (after_regscan)
   629 +    reg_scan_update (exitcode, lastexit, max_reg);
   630  
   631    /* Now copy each insn.  */
   632    for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
   633 diff -urN gcc-2.95.3-orig/gcc/varasm.c gcc-2.95.3/gcc/varasm.c
   634 --- gcc-2.95.3-orig/gcc/varasm.c	Mon Feb 19 15:02:02 2001
   635 +++ gcc-2.95.3/gcc/varasm.c	Fri Jul 20 19:39:11 2001
   636 @@ -3286,7 +3286,10 @@
   637  	  value->un.addr.offset = - INTVAL (XEXP (x, 1));
   638  	}
   639        else
   640 -	abort ();
   641 +	{
   642 +	  value->un.addr.base = x;
   643 +	  value->un.addr.offset = 0;
   644 +	}
   645        break;
   646  
   647      default: