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