Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Sep 2001 18:35:16 -0700
From:      "David O'Brien" <obrien@freebsd.org>
To:        hackers@freebsd.org
Subject:   post 2.95.3 patches to test
Message-ID:  <20010905183516.A68720@dragon.nuxi.com>

next in thread | raw e-mail | index | archive | help
Hi all,

This patch has the "official" GCC 2.95 fixes for sjlj exceptions.
As you may know, the ones we have in our tree are the sjlj changes that
were in 2.95.3.test3, but removed for 2.95.3.test4.

I would like to apply this patch to -current and then -stable afterwards.
I have one good report, from a very good FreeBSD GCC tester.
But before I commit it, I would not mind hearing any one else's
experiences with it.  Replying to the list so all can see is preferred.

-- 
-- David  (obrien@FreeBSD.org)


Index: ChangeLog
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/ChangeLog,v
retrieving revision 1.1.1.12
diff -u -r1.1.1.12 ChangeLog
--- ChangeLog	2001/03/19 19:46:16	1.1.1.12
+++ ChangeLog	2001/08/30 21:05:19
@@ -1,3 +1,160 @@
+2001-08-29  David O'Brien  <obrien@FreeBSD.org>
+
+	* config/alpha/crtbegin.asm: The normal calling convention for alpha is
+	to re-initialize gp using 'ldgp gp,0(ra)' after a jsr instruction.
+
+2001-06-19  Bernd Schmidt  <bernds@redhat.com>
+
+	* regmove.c (optimize_reg_copy_3): Do nothing if previous insn
+	carries a REG_EQUIV note.  If it carries REG_EQUAL, delete the
+	note.
+
+2001-05-22  Bernd Schmidt  <bernds@redhat.com>
+
+	* sparc.md (movsf, movdf): Allow constant to integer reg moves.
+	(movsf, movdf splitters): Always split if there's an alignment
+	problem.
+
+2001-05-22  David Edelsohn  <dje@watson.ibm.com>
+
+	* rs6000.md (movsfcc,movdfcc): Remove NE case.
+
+2001-05-17  Bernd Schmidt  <bernds@redhat.com>
+
+	* function.c: Small formatting change to prevent compilation errors
+	on broken hpux systems.
+
+	* expr.c (protect_from_queue): Protect against subsequent calls to
+	emit_queue.
+	(expand_expr, case ADDR_EXPR): Prevent protect_from_queue from being
+	too clever.
+
+2001-04-06  Bernd Schmidt  <bernds@redhat.com>
+
+	2000-10-17  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
+	* function.c (locate_and_pad_parm): Don't align stack unconditionally.
+
+	Thu Oct 28 10:20:02 1999  Geoffrey Keating  <geoffk@cygnus.com>
+	* config/rs6000/rs6000.md (movsf): Don't convert a SUBREG
+	of the function return register into a plain REG until
+	after function inlining is done.
+
+2001-04-04  Bernd Schmidt  <bernds@redhat.com>
+
+	Fri Nov  5 10:07:25 1999  Nick Clifton  <nickc@cygnus.com>
+	* function.c (is_addressof): New function.  Returns true if
+	the given piece of RTL is an ADDRESSOF.
+	(purge_addressof_1): Make boolean.  Return false if the
+	ADDRESSOFs could not be purged.
+	(purge_addressof): If ADDRESSOFs could not be purged from the
+	notes attached to an insn, remove the offending note(s),
+	unless they are attached to a libcall.
+
+2001-04-03  Bernd Schmidt  <bernds@redhat.com>
+
+	2001-03-16  Jakub Jelinek  <jakub@redhat.com>
+	* crtstuff.c (init_dummy): Use CRT_END_INIT_DUMMY if defined.
+	Remove ia32 linux PIC kludge and move it...
+	* config/i386/linux.h (CRT_END_INIT_DUMMY): ...here.
+
+	* loop.c (combine_movables): Restrict combinations of constants with
+	different modes so that we don't introduce SUBREGs into memory
+	addresses.
+
+	2001-02-02  Philip Blundell  <philb@gnu.org>
+	* arm/linux-elf.h (MAKE_DECL_ONE_ONLY, UNIQUE_SECTION_P): Define.
+	(UNIQUE_SECTION): Define.                                  
+
+	Wed Aug 25 15:27:22 1999  Gavin Romig-Koch  <gavin@cygnus.com>
+	* combine.c (nonzero_bits) : Allow single-ly set registers to be
+	anywere in the function only if they are pseudos and set before
+	being used (not live at the start of the function).
+	(num_sign_bit_copies) : Same.
+	(get_last_value_validate) : Same.
+	(get_last_value) : Same.
+
+	Fri Mar  3 12:49:28 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+        * reload1.c (reload_combine_note_use): Handle return register USEs.
+	REG case: Handle multi-hard-register hard regs.
+
+2001-03-30  Bernd Schmidt  <bernds@redhat.com>
+
+	* jump.c (delete_barrier_successors): Fix error in last change.
+
+	* reload1.c (delete_output_reload): Call eliminate_regs on substed.
+	(reload_as_needed): Call update_eliminable_offsets a bit later.
+
+	* final.c (cleanup_subreg_operands): Also clean up inside MEMs.
+
+	Mon Oct  4 02:31:20 1999  Mark Mitchell  <mark@codesourcery.com>
+	* mips.md: Define conditional move patterns for floating point
+	operands and DI mode conditions.
+
+	2000-11-25  Jakub Jelinek  <jakub@redhat.com>
+	* config/sparc/sparc.md (muldi3_v8plus): Remove H constraint.
+	Handle CONST_INT as second argument.
+
+2001-03-28  Bernd Schmidt  <bernds@redhat.com>
+
+	* flow.c (propagate_block): When trying to delete a case vector, cope
+	if its label has LABEL_PRESERVE_P set.
+	* jump.c (jump_optimize_1): Move call to delete_barrier_successors to
+	a point where JUMP_LABELS and LABEL_NUSES are set up properly.
+	(delete_barrier_successors): If deleting a table jump, delete the case
+	vector as well.
+	* varasm.c (force_const_mem): If we have a label, set LABEL_PRESERVE_P
+	so it won't get deleted.
+
+Tue Mar 20 18:31:48 2001  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+	1999-11-30  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+        * c-lex.c (yylex): With -Wtraditional, when the ANSI type of an
+	integer constant does not match the traditional type, limit the
+	warnings to cases where the base of the type is ten.
+
+        * invoke.texi (-Wtraditional): Document it.
+
+2001-03-20  David O'Brien  <obrien@FreeBSD.org>
+
+	from 2000-07-12  Zack Weinberg  <zack@wolery.cumb.org>
+	* final.c (profile_function): Do not emit profile counters in
+	the data section, if NO_PROFILE_COUNTERS is defined.
+	* tm.texi: Document NO_PROFILE_COUNTERS.  Update doc for
+	FUNCTION_PROFILER.
+
+	from 2000-10-02  David O'Brien  <obrien@dragon.nuxi.com>
+	* config/i386/freebsd.h (NO_PROFILE_COUNTERS): Define.
+
+2001-03-19  Bernd Schmidt  <bernds@redhat.com>
+
+	* version.c: Bump.
+
+	2000-01-18  Martin v. Löwis  <loewis@informatik.hu-berlin.de>
+	* c-parse.in (SAVE_WARN_FLAGS): Create an INTEGER_CST.
+	(RESTORE_WARN_FLAGS): Unpack it.
+	Change semantic type of extension to ttype.
+	* c-common.c (split_specs_attrs): Expect an INTEGER_CST.
+	* c-parse.y, c-parse.c, objc/objc-parse.y,
+	objc/objc-parse.c: Regenerate.
+
+	Wed Sep  1 09:12:02 1999  Jim Kingdon  <http://developer.redhat.com>;
+	* c-parse.in: save and restore warn_pointer_arith on __extension__
+	along with pedantic.
+	(SAVE_WARN_FLAGS, RESTORE_WARN_FLAGS): Added.
+	Set the type of extension to itype rather than $<itype>1 kludge.
+	* extend.texi (Alternate Keywords): Adjust documentation.
+
+	Bring back the sjlj eh fixes.
+	* expr.c (expand_builtin_setjmp_setup): New.
+	(expand_builtin_setjmp_receiver): New.
+	(expand_builtin_setjmp): Split out _setup and _receiver functions.
+	Move argument parsing in from ...
+	(expand_builtin): ... here.
+	* except.c (receive_exception_label): Branch around receiver
+	unless new-style exceptions.  Call expand_builtin_setjmp_receiver.
+	(start_dynamic_handler): Call expand_builtin_setjmp_setup.
+	* expr.h: Update builtin setjmp decls.
+
 Fri Mar 16 12:46:19 GMT 2001 Bernd Schmidt  (bernds@redhat.com)
 
 	* gcc-2.95.3 Released.
Index: c-common.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/c-common.c,v
retrieving revision 1.12
diff -u -r1.12 c-common.c
--- c-common.c	2001/05/25 19:00:07	1.12
+++ c-common.c	2001/08/30 21:05:19
@@ -983,6 +983,15 @@
 {
   tree t, s, a, next, specs, attrs;
 
+  /* This can happen after an __extension__ in pedantic mode.  */
+  if (specs_attrs != NULL_TREE 
+      && TREE_CODE (specs_attrs) == INTEGER_CST)
+    {
+      *declspecs = NULL_TREE;
+      *prefix_attributes = NULL_TREE;
+      return;
+    }
+
   /* This can happen in c++ (eg: decl: typespec initdecls ';').  */
   if (specs_attrs != NULL_TREE
       && TREE_CODE (specs_attrs) != TREE_LIST)
Index: c-lex.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/c-lex.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 c-lex.c
--- c-lex.c	1999/10/16 06:01:50	1.1.1.3
+++ c-lex.c	2001/08/30 21:05:19
@@ -1812,7 +1812,11 @@
 
 	    type = flag_traditional ? traditional_type : ansi_type;
 
-	    if (warn_traditional && traditional_type != ansi_type)
+	    /* We assume that constants specified in a non-decimal
+	       base are bit patterns, and that the programmer really
+	       meant what they wrote.  */
+	    if (warn_traditional && base == 10
+		&& traditional_type != ansi_type)
 	      {
 		if (TYPE_PRECISION (traditional_type)
 		    != TYPE_PRECISION (ansi_type))
Index: c-parse.in
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/c-parse.in,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 c-parse.in
--- c-parse.in	1999/10/16 06:01:51	1.1.1.3
+++ c-parse.in	2001/08/30 21:05:20
@@ -186,7 +186,7 @@
 %type <ttype> init maybeasm
 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
 %type <ttype> maybe_attribute attributes attribute attribute_list attrib
-%type <ttype> any_word
+%type <ttype> any_word extension
 
 %type <ttype> compstmt
 
@@ -247,6 +247,17 @@
 /* 1 if we explained undeclared var errors.  */
 static int undeclared_variable_notice;
 
+/* For __extension__, save/restore the warning flags which are
+   controlled by __extension__.  */
+#define SAVE_WARN_FLAGS()	\
+	build_int_2 (pedantic | (warn_pointer_arith << 1), 0)
+#define RESTORE_WARN_FLAGS(tval) \
+  do {                                     \
+    int val = TREE_INT_CST_LOW (tval);     \
+    pedantic = val & 1;                    \
+    warn_pointer_arith = (val >> 1) & 1;   \
+  } while (0)
+
 ifobjc
 /* Objective-C specific information */
 
@@ -307,7 +318,7 @@
 		  else
 		    error ("argument of `asm' is not a constant string"); }
 	| extension extdef
-		{ pedantic = $<itype>1; }
+		{ RESTORE_WARN_FLAGS ($1); }
 	;
 
 datadef:
@@ -448,7 +459,7 @@
 	/* __extension__ turns off -pedantic for following primary.  */
 	| extension cast_expr	  %prec UNARY
 		{ $$ = $2;
-		  pedantic = $<itype>1; }
+		  RESTORE_WARN_FLAGS ($1); }
 	| unop cast_expr  %prec UNARY
 		{ $$ = build_unary_op ($1, $2, 0);
 		  overflow_warning ($$); }
@@ -1015,7 +1026,7 @@
 	| declmods ';'
 		{ pedwarn ("empty declaration"); }
 	| extension decl
-		{ pedantic = $<itype>1; }
+		{ RESTORE_WARN_FLAGS ($1); }
 	;
 
 /* Declspecs which contain at least one type specifier or typedef name.
@@ -1614,7 +1625,7 @@
 		{ $$ = NULL_TREE; }
 	| extension component_decl
 		{ $$ = $2;
-		  pedantic = $<itype>1; }
+		  RESTORE_WARN_FLAGS ($1); }
 	;
 
 components:
@@ -2426,8 +2437,9 @@
 
 extension:
 	EXTENSION
-		{ $<itype>$ = pedantic;
-		  pedantic = 0; }
+		{ $$ = SAVE_WARN_FLAGS();
+		  pedantic = 0;
+		  warn_pointer_arith = 0; }
 	;
 
 ifobjc
Index: combine.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/combine.c,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 combine.c
--- combine.c	2001/02/17 08:35:07	1.1.1.6
+++ combine.c	2001/08/30 21:05:20
@@ -7580,8 +7580,11 @@
 
       if (reg_last_set_value[REGNO (x)] != 0
 	  && reg_last_set_mode[REGNO (x)] == mode
-	  && (REG_N_SETS (REGNO (x)) == 1
-	      || reg_last_set_label[REGNO (x)] == label_tick)
+	  && (reg_last_set_label[REGNO (x)] == label_tick
+	      || (REGNO (x) >= FIRST_PSEUDO_REGISTER
+		  && REG_N_SETS (REGNO (x)) == 1
+		  && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, 
+					REGNO (x))))
 	  && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
 	return reg_last_set_nonzero_bits[REGNO (x)];
 
@@ -7970,8 +7973,11 @@
 
       if (reg_last_set_value[REGNO (x)] != 0
 	  && reg_last_set_mode[REGNO (x)] == mode
-	  && (REG_N_SETS (REGNO (x)) == 1
-	      || reg_last_set_label[REGNO (x)] == label_tick)
+	  && (reg_last_set_label[REGNO (x)] == label_tick
+	      || (REGNO (x) >= FIRST_PSEUDO_REGISTER
+		  && REG_N_SETS (REGNO (x)) == 1
+		  && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
+					REGNO (x))))
 	  && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
 	return reg_last_set_sign_bit_copies[REGNO (x)];
 
@@ -10819,9 +10825,11 @@
 
       for (j = regno; j < endregno; j++)
 	if (reg_last_set_invalid[j]
-	    /* If this is a pseudo-register that was only set once, it is
-	       always valid.  */
-	    || (! (regno >= FIRST_PSEUDO_REGISTER && REG_N_SETS (regno) == 1)
+	    /* If this is a pseudo-register that was only set once and not
+	       live at the beginning of the function, it is always valid.  */
+	    || (! (regno >= FIRST_PSEUDO_REGISTER 
+		   && REG_N_SETS (regno) == 1
+		   && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno))
 		&& reg_last_set_label[j] > tick))
 	  {
 	    if (replace)
@@ -10880,12 +10888,21 @@
   regno = REGNO (x);
   value = reg_last_set_value[regno];
 
-  /* If we don't have a value or if it isn't for this basic block,
-     return 0.  */
+  /* If we don't have a value, or if it isn't for this basic block and
+     it's either a hard register, set more than once, or it's a live
+     at the beginning of the function, return 0.  
+
+     Because if it's not live at the beginnning of the function then the reg 
+     is always set before being used (is never used without being set).
+     And, if it's set only once, and it's always set before use, then all
+     uses must have the same last value, even if it's not from this basic
+     block.  */
 
   if (value == 0
-      || (REG_N_SETS (regno) != 1
-	  && reg_last_set_label[regno] != label_tick))
+      || (reg_last_set_label[regno] != label_tick
+	  && (regno < FIRST_PSEUDO_REGISTER
+	      || REG_N_SETS (regno) != 1
+	      || REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno))))
     return 0;
 
   /* If the value was set in a later insn than the ones we are processing,
Index: crtstuff.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/crtstuff.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 crtstuff.c
--- crtstuff.c	1999/10/16 06:03:46	1.1.1.3
+++ crtstuff.c	2001/08/30 21:05:31
@@ -380,19 +380,8 @@
 #endif
   asm (TEXT_SECTION_ASM_OP);
 
-/* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr,
-   __environ and atexit (). We have to make sure they are in the .dynsym
-   section. We accomplish it by making a dummy call here. This
-   code is never reached.  */
- 
-#if defined(__linux__) && defined(__PIC__) && defined(__i386__)
-  {
-    extern void *___brk_addr;
-    extern char **__environ;
-
-    ___brk_addr = __environ;
-    atexit ();
-  }
+#ifdef CRT_END_INIT_DUMMY
+  CRT_END_INIT_DUMMY;
 #endif
 }
 
Index: cse.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/cse.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 cse.c
--- cse.c	2001/02/17 08:35:14	1.1.1.7
+++ cse.c	2001/08/30 21:05:31
@@ -695,8 +695,6 @@
 static struct cse_reg_info* get_cse_reg_info PROTO((int));
 static void free_cse_reg_info   PROTO((splay_tree_value));
 static void flush_hash_table	PROTO((void));
-
-extern int rtx_equal_function_value_matters;
 
 /* Dump the expressions in the equivalence class indicated by CLASSP.
    This function is used only for debugging.  */
Index: except.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/except.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 except.c
--- except.c	2001/03/24 01:58:31	1.1.1.5
+++ except.c	2001/08/30 21:05:32
@@ -733,20 +733,20 @@
     }
 
   emit_label (handler_label);
-  
+
   if (! exceptions_via_longjmp)
     {
 #ifdef HAVE_exception_receiver
       if (HAVE_exception_receiver)
-       emit_insn (gen_exception_receiver ());
+	emit_insn (gen_exception_receiver ());
       else
 #endif
 #ifdef HAVE_nonlocal_goto_receiver
       if (HAVE_nonlocal_goto_receiver)
-       emit_insn (gen_nonlocal_goto_receiver ());
+	emit_insn (gen_nonlocal_goto_receiver ());
       else
 #endif
-       { /* Nothing */ }
+	{ /* Nothing */ }
     }
   else
     {
Index: expr.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/expr.c,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 expr.c
--- expr.c	2001/03/24 01:58:30	1.1.1.8
+++ expr.c	2001/08/30 21:05:32
@@ -450,6 +450,9 @@
 				QUEUED_INSN (y));
 	      return temp;
 	    }
+	  /* Copy the address into a pseudo, so that the returned value
+	     remains correct across calls to emit_queue.  */
+	  XEXP (new, 0) = copy_to_reg (XEXP (new, 0));
 	  return new;
 	}
       /* Otherwise, recursively protect the subexpressions of all
@@ -476,9 +479,11 @@
 	}
       return x;
     }
-  /* If the increment has not happened, use the variable itself.  */
+  /* If the increment has not happened, use the variable itself.  Copy it
+     into a new pseudo so that the value remains correct across calls to
+     emit_queue.  */
   if (QUEUED_INSN (x) == 0)
-    return QUEUED_VAR (x);
+    return copy_to_reg (QUEUED_VAR (x));
   /* If the increment has happened and a pre-increment copy exists,
      use that copy.  */
   if (QUEUED_COPY (x) != 0)
@@ -8077,7 +8082,9 @@
 	  if (ignore)
 	    return op0;
 
-	  op0 = protect_from_queue (op0, 0);
+	  /* Pass 1 for MODIFY, so that protect_from_queue doesn't get
+	     clever and returns a REG when given a MEM.  */
+	  op0 = protect_from_queue (op0, 1);
 
 	  /* We would like the object in memory.  If it is a constant,
 	     we can have it be statically allocated into memory.  For
@@ -8603,7 +8610,7 @@
 
 /* Construct the trailing part of a __builtin_setjmp call.
    This is used directly by sjlj exception handling code.  */
- 
+
 void
 expand_builtin_setjmp_receiver (receiver_label)
       rtx receiver_label ATTRIBUTE_UNUSED;
@@ -8726,7 +8733,7 @@
   current_function_has_nonlocal_label = 1;
   nonlocal_goto_handler_labels
     = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
- 
+
   return target;
 }
 
Index: final.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/final.c,v
retrieving revision 1.9
diff -u -r1.9 final.c
--- final.c	2001/03/19 20:32:45	1.9
+++ final.c	2001/08/30 21:07:13
@@ -3055,7 +3055,8 @@
       if (GET_CODE (recog_operand[i]) == SUBREG)
         recog_operand[i] = alter_subreg (recog_operand[i]);
       else if (GET_CODE (recog_operand[i]) == PLUS
-               || GET_CODE (recog_operand[i]) == MULT)
+               || GET_CODE (recog_operand[i]) == MULT
+	       || GET_CODE (recog_operand[i]) == MEM)
        recog_operand[i] = walk_alter_subreg (recog_operand[i]);
     }
 
@@ -3064,7 +3065,8 @@
       if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
         *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
       else if (GET_CODE (*recog_dup_loc[i]) == PLUS
-               || GET_CODE (*recog_dup_loc[i]) == MULT)
+               || GET_CODE (*recog_dup_loc[i]) == MULT
+	       || GET_CODE (*recog_dup_loc[i]) == MEM)
         *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
     }
 }
Index: flow.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/flow.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 flow.c
--- flow.c	2001/02/17 08:35:29	1.1.1.5
+++ flow.c	2001/08/30 21:05:38
@@ -2744,15 +2744,23 @@
 		{
 		  if (REG_NOTE_KIND (inote) == REG_LABEL)
 		    {
+		      int n_forced;
 		      rtx label = XEXP (inote, 0);
 		      rtx next;
 		      LABEL_NUSES (label)--;
 
+		      /* The label may be forced if it has been put in the
+		         constant pool.  We can't delete it in this case, but
+		         we still must discard a jump table following it.  */
+		      n_forced = 0;
+		      if (LABEL_PRESERVE_P (label))
+			n_forced++;
+
 		      /* If this label was attached to an ADDR_VEC, it's
 			 safe to delete the ADDR_VEC.  In fact, it's pretty much
 			 mandatory to delete it, because the ADDR_VEC may
 			 be referencing labels that no longer exist.  */
-		      if (LABEL_NUSES (label) == 0
+		      if (LABEL_NUSES (label) == n_forced
 			  && (next = next_nonnote_insn (label)) != NULL
 			  && GET_CODE (next) == JUMP_INSN
 			  && (GET_CODE (PATTERN (next)) == ADDR_VEC
Index: function.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/function.c,v
retrieving revision 1.8
diff -u -r1.8 function.c
--- function.c	2001/02/17 09:03:40	1.8
+++ function.c	2001/08/30 21:05:38
@@ -515,8 +515,9 @@
 static int contains		PROTO((rtx, int *));
 #endif /* HAVE_prologue || HAVE_epilogue */
 static void put_addressof_into_stack PROTO((rtx, struct hash_table *));
-static void purge_addressof_1	PROTO((rtx *, rtx, int, int, 
+static boolean purge_addressof_1 PROTO((rtx *, rtx, int, int, 
 				       struct hash_table *));
+static int is_addressof		PROTO ((rtx *, void *));
 static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
 						       struct hash_table *,
 						       hash_table_key));
@@ -3057,9 +3058,10 @@
 
 /* Helper function for purge_addressof.  See if the rtx expression at *LOC
    in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
-   the stack.  */
+   the stack.  If the function returns FALSE then the replacement could not
+   be made.  */
 
-static void
+static boolean
 purge_addressof_1 (loc, insn, force, store, ht)
      rtx *loc;
      rtx insn;
@@ -3070,13 +3072,14 @@
   RTX_CODE code;
   int i, j;
   char *fmt;
+  boolean result = true;
 
   /* Re-start here to avoid recursion in common cases.  */
  restart:
 
   x = *loc;
   if (x == 0)
-    return;
+    return true;
 
   code = GET_CODE (x);
 
@@ -3089,7 +3092,7 @@
 
       if (validate_change (insn, loc, sub, 0)
 	  || validate_replace_rtx (x, sub, insn))
-	return;
+	return true;
   
       start_sequence ();
       sub = force_operand (sub, NULL_RTX);
@@ -3100,7 +3103,7 @@
       insns = gen_sequence ();
       end_sequence ();
       emit_insn_before (insns, insn);
-      return;
+      return true;
     }
   else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
     {
@@ -3119,7 +3122,7 @@
 	  && (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
 	{
 	  put_addressof_into_stack (XEXP (x, 0), ht);
-	  return;
+	  return true;
 	}
       else if (GET_CODE (sub) == REG && GET_MODE (x) != GET_MODE (sub))
 	{
@@ -3138,7 +3141,7 @@
 		if (rtx_equal_p (x, XEXP (tem, 0)))
 		  {
 		    *loc = XEXP (XEXP (tem, 1), 0);
-		    return;
+		    return true;
 		  }
 
 	      /* See comment for purge_addressof_replacements. */
@@ -3178,11 +3181,17 @@
 		      z = gen_lowpart (GET_MODE (x), z);
 
 		    *loc = z;
-		    return;
+		    return true;
 		  }
 
-	      /* There should always be such a replacement.  */
-	      abort ();
+	      /* Sometimes we may not be able to find the replacement.  For
+		 example when the original insn was a MEM in a wider mode,
+		 and the note is part of a sign extension of a narrowed
+		 version of that MEM.  Gcc testcase compile/990829-1.c can
+		 generate an example of this siutation.  Rather than complain
+		 we return false, which will prompt our caller to remove the
+		 offending note.  */
+	      return false;
 	    }
 
 	  size_x = GET_MODE_BITSIZE (GET_MODE (x));
@@ -3268,7 +3277,7 @@
 				      purge_bitfield_addressof_replacements));
 
 	      /* We replaced with a reg -- all done.  */
-	      return;
+	      return true;
 	    }
 	}
       else if (validate_change (insn, loc, sub, 0))
@@ -3285,13 +3294,13 @@
 		if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
 		  {
 		    XEXP (XEXP (tem, 1), 0) = sub;
-		    return;
+		    return true;
 		  }
 	      purge_addressof_replacements
 		= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
 			   gen_rtx_EXPR_LIST (VOIDmode, sub,
 					      purge_addressof_replacements));
-	      return;
+	      return true;
 	    }
 	  goto restart;
 	}
@@ -3301,13 +3310,13 @@
   else if (code == ADDRESSOF)
     {
       put_addressof_into_stack (x, ht);
-      return;
+      return true;
     }
   else if (code == SET)
     {
-      purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
-      purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
-      return;
+      result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
+      result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
+      return result;
     }
 
   /* Scan all subexpressions. */
@@ -3315,11 +3324,13 @@
   for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
     {
       if (*fmt == 'e')
-	purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
+	result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
       else if (*fmt == 'E')
 	for (j = 0; j < XVECLEN (x, i); j++)
-	  purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
+	  result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
     }
+
+  return result;
 }
 
 /* Return a new hash table entry in HT.  */
@@ -3439,6 +3450,16 @@
 	}
 }
 
+/* Helper function for purge_addressof called through for_each_rtx.
+   Returns true iff the rtl is an ADDRESSOF.  */
+static int
+is_addressof (rtl, data)
+     rtx * rtl;
+     void * data ATTRIBUTE_UNUSED;
+{
+  return GET_CODE (* rtl) == ADDRESSOF;
+}
+
 /* Eliminate all occurrences of ADDRESSOF from INSNS.  Elide any remaining
    (MEM (ADDRESSOF)) patterns, and force any needed registers into the
    stack.  */
@@ -3467,9 +3488,30 @@
     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
 	|| GET_CODE (insn) == CALL_INSN)
       {
-	purge_addressof_1 (&PATTERN (insn), insn,
-			   asm_noperands (PATTERN (insn)) > 0, 0, &ht);
-	purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht);
+	if (! purge_addressof_1 (&PATTERN (insn), insn,
+				 asm_noperands (PATTERN (insn)) > 0, 0, &ht))
+	  /* If we could not replace the ADDRESSOFs in the insn,
+	     something is wrong.  */
+	  abort ();
+	
+	if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht))
+	  {
+	    /* If we could not replace the ADDRESSOFs in the insn's notes,
+	       we can just remove the offending notes instead.  */
+	    rtx note;
+
+	    for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+	      {
+		/* If we find a REG_RETVAL note then the insn is a libcall.
+		   Such insns must have REG_EQUAL notes as well, in order
+		   for later passes of the compiler to work.  So it is not
+		   safe to delete the notes here, and instead we abort.  */
+		if (REG_NOTE_KIND (note) == REG_RETVAL)
+		  abort ();
+		if (for_each_rtx (& note, is_addressof, NULL))
+		  remove_note (insn, note);
+	      }
+	  }
       }
 
   /* Clean up.  */
@@ -5294,7 +5336,18 @@
 				- offset_ptr->constant); 
     }
 #else /* !ARGS_GROW_DOWNWARD */
-  pad_to_arg_alignment (initial_offset_ptr, boundary);
+  if (!in_regs 
+#ifdef REG_PARM_STACK_SPACE
+      || REG_PARM_STACK_SPACE (fndecl) > 0
+#else
+      /* For the gcc-2_95-branch we want to make sure not to break something
+         on platforms which pass argument in registers but don't define
+         REG_PARM_STACK_SPACE. So we force the original behaviour here.  */
+      || 1
+#endif
+      )
+    pad_to_arg_alignment (initial_offset_ptr, boundary);
+
   *offset_ptr = *initial_offset_ptr;
 
 #ifdef PUSH_ROUNDING
@@ -6936,7 +6989,7 @@
 	    }
 	}
       }
-  #endif
+#endif
 }
 
 /* Reposition the prologue-end and epilogue-begin notes after instruction
Index: invoke.texi
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/invoke.texi,v
retrieving revision 1.8
diff -u -r1.8 invoke.texi
--- invoke.texi	2001/02/17 09:04:50	1.8
+++ invoke.texi	2001/08/30 21:05:38
@@ -1698,6 +1698,12 @@
 @item
 A non-@code{static} function declaration follows a @code{static} one.
 This construct is not accepted by some traditional C compilers.
+
+@item
+The ANSI type of an integer constant has a different width or signedness
+from its traditional type.  This warning is only issued if the base of
+the constant is ten.  I.e. hexadecimal or octal values, which typically
+represent bit patterns, are not warned about.
 @end itemize
 
 @item -Wundef
Index: jump.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/jump.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 jump.c
--- jump.c	1999/11/01 08:26:16	1.1.1.4
+++ jump.c	2001/08/30 21:05:38
@@ -200,8 +200,6 @@
   if (flag_exceptions && cross_jump)
     init_insn_eh_region (f, max_uid);
 
-  delete_barrier_successors (f);
-
   /* Leave some extra room for labels and duplicate exit test insns
      we make.  */
   max_jump_chain = max_uid * 14 / 10;
@@ -224,6 +222,8 @@
   for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
     LABEL_NUSES (XEXP (insn, 0))++;
 
+  delete_barrier_successors (f);
+
   /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
      notes and recompute LABEL_NUSES.  */
   if (mark_labels_only)
@@ -2139,7 +2139,24 @@
 	  insn = NEXT_INSN (insn);
 	  while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
 	    {
-	      if (GET_CODE (insn) == NOTE
+	      if (GET_CODE (insn) == JUMP_INSN)
+		{
+		  /* Detect when we're deleting a tablejump; get rid of
+		     the jump table as well.  */
+		  rtx next1 = next_nonnote_insn (insn);
+		  rtx next2 = next1 ? next_nonnote_insn (next1) : 0;
+		  if (next2 && GET_CODE (next1) == CODE_LABEL
+		      && GET_CODE (next2) == JUMP_INSN
+		      && (GET_CODE (PATTERN (next2)) == ADDR_VEC
+			  || GET_CODE (PATTERN (next2)) == ADDR_DIFF_VEC))
+		    {
+		      delete_insn (insn);
+		      insn = next2;
+		    }
+		  else
+		    insn = delete_insn (insn);
+		}
+	      else if (GET_CODE (insn) == NOTE
 		  && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
 		insn = NEXT_INSN (insn);
 	      else
Index: loop.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/loop.c,v
retrieving revision 1.1.1.9
diff -u -r1.1.1.9 loop.c
--- loop.c	2001/02/17 08:35:49	1.1.1.9
+++ loop.c	2001/08/30 21:05:38
@@ -1481,10 +1481,16 @@
 		      width as M1.  The check for integer is redundant, but
 		      safe, since the only case of differing destination
 		      modes with equal sources is when both sources are
-		      VOIDmode, i.e., CONST_INT.  */
+		      VOIDmode, i.e., CONST_INT.
+		    
+		      For 2.95, don't do this if the mode of M1 is Pmode.
+		      This prevents us from substituting SUBREGs for REGs
+		      in memory accesses; not all targets are prepared to
+		      handle this properly.  */
 		   (GET_MODE (m->set_dest) == GET_MODE (m1->set_dest)
 		    || (GET_MODE_CLASS (GET_MODE (m->set_dest)) == MODE_INT
 			&& GET_MODE_CLASS (GET_MODE (m1->set_dest)) == MODE_INT
+			&& GET_MODE (m1->set_dest) != Pmode
 			&& (GET_MODE_BITSIZE (GET_MODE (m->set_dest))
 			    >= GET_MODE_BITSIZE (GET_MODE (m1->set_dest)))))
 		   /* See if the source of M1 says it matches M.  */
Index: regmove.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/regmove.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 regmove.c
--- regmove.c	1999/11/01 08:26:31	1.1.1.3
+++ regmove.c	2001/08/30 21:05:38
@@ -693,6 +693,9 @@
     }
   if (! (set = single_set (p))
       || GET_CODE (SET_SRC (set)) != MEM
+      /* If there's a REG_EQUIV note, this must be an insn that loads an
+	 argument.  Prefer keeping the note over doing this optimization.  */
+      || find_reg_note (p, REG_EQUIV, NULL_RTX)
       || SET_DEST (set) != src_reg)
     return;
 
@@ -736,6 +739,12 @@
       /* One or more changes were no good.  Back out everything.  */
       PUT_MODE (src_reg, old_mode);
       XEXP (src, 0) = src_reg;
+    }
+  else
+    {
+      rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
+      if (note)
+	remove_note (p, note);
     }
 }
 
Index: reload1.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/reload1.c,v
retrieving revision 1.1.1.6
diff -u -r1.1.1.6 reload1.c
--- reload1.c	2001/02/17 08:36:02	1.1.1.6
+++ reload1.c	2001/08/30 21:05:38
@@ -4278,9 +4278,6 @@
 			    spill_reg_order);
 	    }
 
-	  if (num_eliminable && chain->need_elim)
-	    update_eliminable_offsets ();
-
 	  if (n_reloads > 0)
 	    {
 	      rtx next = NEXT_INSN (insn);
@@ -4327,6 +4324,10 @@
 		      NOTE_LINE_NUMBER (p) = NOTE_INSN_DELETED;
 		    }
 	    }
+
+	  if (num_eliminable && chain->need_elim)
+	    update_eliminable_offsets ();
+
 	  /* Any previously reloaded spilled pseudo reg, stored in this insn,
 	     is no longer validly lying around to save a future reload.
 	     Note that this does not detect pseudos that were reloaded
@@ -8071,7 +8072,9 @@
     }
   n_occurrences = count_occurrences (PATTERN (insn), reg);
   if (substed)
-    n_occurrences += count_occurrences (PATTERN (insn), substed);
+    n_occurrences += count_occurrences (PATTERN (insn),
+					eliminate_regs (substed, 0,
+							NULL_RTX));
   if (n_occurrences > n_inherited)
     return;
 
@@ -9967,6 +9970,21 @@
 	}
       break;
 
+    case USE:
+      /* If this is the USE of a return value, we can't change it.  */
+      if (GET_CODE (XEXP (x, 0)) == REG && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
+	{
+	/* Mark the return register as used in an unknown fashion.  */
+	  rtx reg = XEXP (x, 0);
+	  int regno = REGNO (reg);
+	  int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+
+	  while (--nregs >= 0)
+	    reg_state[regno + nregs].use_index = -1;
+	  return;
+	}
+      break;
+
     case CLOBBER:
       if (GET_CODE (SET_DEST (x)) == REG)
 	return;
@@ -9983,11 +10001,22 @@
       {
 	int regno = REGNO (x);
 	int use_index;
+	int nregs;
 
 	/* Some spurious USEs of pseudo registers might remain.
 	   Just ignore them.  */
 	if (regno >= FIRST_PSEUDO_REGISTER)
 	  return;
+
+	nregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
+
+	/* We can't substitute into multi-hard-reg uses.  */
+	if (nregs > 1)
+	  {
+	    while (--nregs >= 0)
+	      reg_state[regno + nregs].use_index = -1;
+	    return;
+	  }
 
 	/* If this register is already used in some unknown fashion, we
 	   can't do anything.
Index: rtl.h
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/rtl.h,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 rtl.h
--- rtl.h	2001/02/17 08:36:04	1.1.1.5
+++ rtl.h	2001/08/30 21:05:38
@@ -888,6 +888,12 @@
 /* For a NOTE_INSN_LIVE note, the original basic block number.  */
 #define RANGE_LIVE_ORIG_BLOCK(INSN) (XINT (INSN, 1))
 
+/* Nonzero if we need to distinguish between the return value of this function
+   and the return value of a function called by this function.  This helps
+   integrate.c.
+   This is 1 until after the rtl generation pass.  */
+extern int rtx_equal_function_value_matters;
+
 /* Generally useful functions.  */
 
 /* The following functions accept a wide integer argument.  Rather than
Index: tm.texi
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/tm.texi,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 tm.texi
--- tm.texi	1999/10/16 06:05:53	1.1.1.3
+++ tm.texi	2001/08/30 21:05:39
@@ -3464,6 +3464,13 @@
 system's installed C compiler and look at the assembler code that
 results.
 
+@findex NO_PROFILE_COUNTERS
+@item NO_PROFILE_COUNTERS
+Define this macro if the @code{mcount} subroutine on your system does
+not need a counter variable allocated for each function.  This is true
+for almost all modern implementations.  If you define this macro, you
+must not use the @var{labelno} argument to @code{FUNCTION_PROFILER}.
+
 @findex PROFILE_BEFORE_PROLOGUE
 @item PROFILE_BEFORE_PROLOGUE
 Define this macro if the code for function profiling should come before
Index: toplev.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/toplev.c,v
retrieving revision 1.12
diff -u -r1.12 toplev.c
--- toplev.c	2001/08/16 06:05:18	1.12
+++ toplev.c	2001/08/30 21:05:39
@@ -139,8 +139,6 @@
 #define DIR_SEPARATOR '/'
 #endif
 
-extern int rtx_equal_function_value_matters;
-
 #if ! (defined (VMS) || defined (OS2))
 extern char **environ;
 #endif
Index: varasm.c
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/varasm.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 varasm.c
--- varasm.c	2001/03/24 01:58:28	1.1.1.7
+++ varasm.c	2001/08/30 21:05:39
@@ -3494,18 +3494,9 @@
 
 	  pop_obstacks ();
 	}
-      if (GET_CODE (x) == LABEL_REF)
-	{
-	  extern rtx forced_labels;
-
-	  push_obstacks_nochange ();
-	  rtl_in_saveable_obstack ();
 
-	  forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
-					     XEXP (x, 0),
-					     forced_labels);
-	  pop_obstacks ();
-	}
+      if (GET_CODE (x) == LABEL_REF)
+	LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
 
       /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
 
Index: config/i386/linux.h
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/config/i386/linux.h,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 linux.h
--- config/i386/linux.h	1999/10/16 06:08:08	1.1.1.4
+++ config/i386/linux.h	2001/08/30 21:05:26
@@ -234,3 +234,21 @@
     }									\
   } while (0)
 #endif
+
+#if defined(__PIC__) && defined (USE_GNULIBC_1)
+/* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr,
+   __environ and atexit (). We have to make sure they are in the .dynsym
+   section. We accomplish it by making a dummy call here. This
+   code is never reached.  */
+         
+#define CRT_END_INIT_DUMMY		\
+  do					\
+    {					\
+      extern void *___brk_addr;		\
+      extern char **__environ;		\
+					\
+      ___brk_addr = __environ;		\
+      atexit (0);			\
+    }					\
+  while (0)
+#endif
Index: config/sparc/sparc.md
===================================================================
RCS file: /home/ncvs/src/contrib/gcc.295/config/sparc/sparc.md,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 sparc.md
--- config/sparc/sparc.md	2001/02/17 08:37:45	1.1.1.5
+++ config/sparc/sparc.md	2001/08/30 21:05:31
@@ -2899,6 +2899,11 @@
          crashes in output_constant_pool.  */
       if (operands [1] == const0_rtx)
         operands[1] = CONST0_RTX (SFmode);
+      /* We are able to build any SF constant in integer registers
+	 with at most 2 instructions.  */
+      if (REGNO (operands[0]) < 32)
+	goto movsf_is_ok;
+
       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
                                                    operands[1]));
     }
@@ -3093,6 +3098,9 @@
          crashes in output_constant_pool.  */
       if (operands [1] == const0_rtx)
         operands[1] = CONST0_RTX (DFmode);
+      if (REGNO (operands[0]) < 32)
+	goto movdf_is_ok;
+
       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
                                                    operands[1]));
     }
@@ -3277,17 +3285,11 @@
 (define_split
   [(set (match_operand:DF 0 "register_operand" "")
 	(match_operand:DF 1 "memory_operand" ""))]
-  "((! TARGET_V9
-     || (! TARGET_ARCH64
-         && ((GET_CODE (operands[0]) == REG
-              && REGNO (operands[0]) < 32)
-             || (GET_CODE (operands[0]) == SUBREG
-                 && GET_CODE (SUBREG_REG (operands[0])) == REG
-                 && REGNO (SUBREG_REG (operands[0])) < 32))))
-    && (reload_completed
-        && (((REGNO (operands[0])) % 2) != 0
-             || ! mem_min_alignment (operands[1], 8))
-        && offsettable_memref_p (operands[1])))"
+  "reload_completed
+   && ! TARGET_ARCH64
+   && (((REGNO (operands[0]) % 2) != 0)
+       || ! mem_min_alignment (operands[1], 8))
+   && offsettable_memref_p (operands[1])"
   [(clobber (const_int 0))]
   "
 {
@@ -3318,17 +3320,11 @@
 (define_split
   [(set (match_operand:DF 0 "memory_operand" "")
 	(match_operand:DF 1 "register_operand" ""))]
-  "((! TARGET_V9
-     || (! TARGET_ARCH64
-         && ((GET_CODE (operands[1]) == REG
-              && REGNO (operands[1]) < 32)
-             || (GET_CODE (operands[1]) == SUBREG
-                 && GET_CODE (SUBREG_REG (operands[1])) == REG
-                 && REGNO (SUBREG_REG (operands[1])) < 32))))
-    && (reload_completed
-        && (((REGNO (operands[1])) % 2) != 0
-             || ! mem_min_alignment (operands[0], 8))
-        && offsettable_memref_p (operands[0])))"
+  "reload_completed
+   && ! TARGET_ARCH64
+   && (((REGNO (operands[1]) % 2) != 0)
+       || ! mem_min_alignment (operands[0], 8))
+   && offsettable_memref_p (operands[0])"
   [(clobber (const_int 0))]
   "
 {
@@ -5211,7 +5207,7 @@
 (define_insn "muldi3_v8plus"
   [(set (match_operand:DI 0 "register_operand" "=r,h")
 	(mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
-		 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
+		 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
    (clobber (match_scratch:SI 3 "=&h,X"))
    (clobber (match_scratch:SI 4 "=&h,X"))]
   "TARGET_V8PLUS"
@@ -5221,6 +5217,13 @@
     output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
   if (which_alternative == 1)
     output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
+  if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      if (which_alternative == 1)
+	return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
+      else
+	return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
+    }
   if (sparc_check_64 (operands[2], insn) <= 0)
     output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
   if (which_alternative == 1)

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010905183516.A68720>