Index: trunk/src/gcc/gcc/config/alpha/alpha.c
===================================================================
--- trunk/src/gcc/gcc/config/alpha/alpha.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/alpha/alpha.c	(revision 1469)
@@ -504,4 +504,7 @@
 	  alpha_fptm = ALPHA_FPTM_SU;
 	}
+      if (target_flags_explicit & MASK_LONG_DOUBLE_128)
+	warning ("128-bit long double not supported for VAX floats");
+      target_flags &= ~MASK_LONG_DOUBLE_128;
     }
 
@@ -1825,4 +1828,8 @@
   /* We want to merge strings, so we never consider them small data.  */
   if (TREE_CODE (exp) == STRING_CST)
+    return false;
+
+  /* Functions are never in the small data area.  Duh.  */
+  if (TREE_CODE (exp) == FUNCTION_DECL)
     return false;
 
Index: trunk/src/gcc/gcc/config/alpha/alpha.h
===================================================================
--- trunk/src/gcc/gcc/config/alpha/alpha.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/alpha/alpha.h	(revision 1469)
@@ -68,4 +68,6 @@
 	if (TARGET_IEEE_WITH_INEXACT)			\
 	  builtin_define ("_IEEE_FP_INEXACT");		\
+	if (TARGET_LONG_DOUBLE_128)			\
+	  builtin_define ("__LONG_DOUBLE_128__");	\
 							\
 	/* Macros dependent on the C dialect.  */	\
@@ -223,4 +225,9 @@
 #define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL)
 
+/* This means use IEEE quad-format for long double.  Assumes the 
+   presence of the GEM support library routines.  */
+#define MASK_LONG_DOUBLE_128 (1 << 16)
+#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
+
 /* This means that the processor is an EV5, EV56, or PCA56.
    Unlike alpha_cpu this is not affected by -mtune= setting.  */
@@ -255,5 +262,5 @@
 #endif
 #ifndef TARGET_HAS_XFLOATING_LIBS
-#define TARGET_HAS_XFLOATING_LIBS 0
+#define TARGET_HAS_XFLOATING_LIBS TARGET_LONG_DOUBLE_128
 #endif
 #ifndef TARGET_PROFILING_NEEDS_GP
@@ -313,4 +320,8 @@
     {"tls-kernel", MASK_TLS_KERNEL,					\
      N_("Emit rdval instead of rduniq for thread pointer")},		\
+    {"long-double-128", MASK_LONG_DOUBLE_128,				\
+     N_("Use 128-bit long double")},					\
+    {"long-double-64", -MASK_LONG_DOUBLE_128,				\
+     N_("Use 64-bit long double")},					\
     {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT				\
 	 | TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
@@ -423,5 +434,16 @@
 #define FLOAT_TYPE_SIZE 32
 #define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+
+/* Define this to set long double type size to use in libgcc2.c, which can
+   not depend on target_flags.  */
+#ifdef __LONG_DOUBLE_128__
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#endif
+
+/* Work around target_flags dependency in ada/targtyps.c.  */
+#define WIDEST_HARDWARE_FP_SIZE 64
 
 #define	WCHAR_TYPE "unsigned int"
@@ -484,5 +506,5 @@
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
-#define STACK_BOUNDARY 64
+#define STACK_BOUNDARY 128
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
@@ -623,10 +645,9 @@
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
    On Alpha, the integer registers can hold any mode.  The floating-point
-   registers can hold 32-bit and 64-bit integers as well, but not 16-bit
-   or 8-bit values.  */
+   registers can hold 64-bit integers as well, but not smaller values.  */
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE) 				\
   ((REGNO) >= 32 && (REGNO) <= 62 					\
-   ? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4	\
+   ? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode		\
    : 1)
 
Index: trunk/src/gcc/gcc/config/alpha/alpha.md
===================================================================
--- trunk/src/gcc/gcc/config/alpha/alpha.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/alpha/alpha.md	(revision 1469)
@@ -31,5 +31,5 @@
    (UNSPEC_MSKXH	3)
    (UNSPEC_CVTQL	4)
-   (UNSPEC_NT_LDA	5)
+   (UNSPEC_CVTLQ	5)
    (UNSPEC_UMK_LAUM	6)
    (UNSPEC_UMK_LALM	7)
@@ -59,4 +59,7 @@
    (UNSPEC_CTLZ		27)
    (UNSPEC_CTPOP	28)
+
+   ;; Legacy
+   (UNSPEC_NT_LDA	29)
   ])
 
@@ -181,32 +184,24 @@
   "")
 
-(define_insn "*extendsidi2_nofix"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
+(define_insn "*cvtlq"
+  [(set (match_operand:DI 0 "register_operand" "=f")
+	(unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
+		   UNSPEC_CVTLQ))]
+  ""
+  "cvtlq %1,%0"
+  [(set_attr "type" "fadd")])
+
+(define_insn "*extendsidi2_1"
+  [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
 	(sign_extend:DI
-	  (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
-  "! TARGET_FIX"
+	  (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
+  ""
   "@
    addl $31,%1,%0
    ldl %0,%1
-   cvtlq %1,%0
    lds %0,%1\;cvtlq %0,%0"
-  [(set_attr "type" "iadd,ild,fadd,fld")
-   (set_attr "length" "*,*,*,8")])
-
-(define_insn "*extendsidi2_fix"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f")
-	(sign_extend:DI
-	  (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
-  "TARGET_FIX"
-  "@
-   addl $31,%1,%0
-   ldl %0,%1
-   ftois %1,%0
-   cvtlq %1,%0
-   lds %0,%1\;cvtlq %0,%0"
-  [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
-   (set_attr "length" "*,*,*,*,8")])
-
-;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
+  [(set_attr "type" "iadd,ild,fld")
+   (set_attr "length" "*,*,8")])
+
 (define_split
   [(set (match_operand:DI 0 "hard_fp_register_operand" "")
@@ -214,6 +209,9 @@
   "reload_completed"
   [(set (match_dup 2) (match_dup 1))
-   (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
-  "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+   (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+  operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
 
 ;; Optimize sign-extension of SImode loads.  This shows up in the wake of
@@ -227,26 +225,4 @@
   "true_regnum (operands[0]) == true_regnum (operands[2])
    || peep2_reg_dead_p (2, operands[0])"
-  [(set (match_dup 2)
-	(sign_extend:DI (match_dup 1)))]
-  "")
-
-(define_peephole2
-  [(set (match_operand:SI 0 "hard_int_register_operand" "")
-        (match_operand:SI 1 "hard_fp_register_operand" ""))
-   (set (match_operand:DI 2 "hard_int_register_operand" "")
-        (sign_extend:DI (match_dup 0)))]
-  "TARGET_FIX
-   && (true_regnum (operands[0]) == true_regnum (operands[2])
-       || peep2_reg_dead_p (2, operands[0]))"
-  [(set (match_dup 2)
-	(sign_extend:DI (match_dup 1)))]
-  "")
-
-(define_peephole2
-  [(set (match_operand:DI 0 "hard_fp_register_operand" "")
-        (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
-   (set (match_operand:DI 2 "hard_int_register_operand" "")
-        (match_dup 0))]
-  "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
   [(set (match_dup 2)
 	(sign_extend:DI (match_dup 1)))]
@@ -2314,6 +2290,6 @@
 
 (define_insn "*cvtql"
-  [(set (match_operand:SI 0 "register_operand" "=f")
-	(unspec:SI [(match_operand:DI 1 "reg_or_0_operand" "fG")]
+  [(set (match_operand:SF 0 "register_operand" "=f")
+	(unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
 		   UNSPEC_CVTQL))]
   "TARGET_FP"
@@ -2327,12 +2303,14 @@
 	(subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
    (clobber (match_scratch:DI 2 "=&f"))
-   (clobber (match_scratch:SI 3 "=&f"))]
+   (clobber (match_scratch:SF 3 "=&f"))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "#"
   "&& reload_completed"
   [(set (match_dup 2) (fix:DI (match_dup 1)))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ""
+   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 5) (match_dup 3))]
+{
+  operands[5] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
@@ -2346,8 +2324,10 @@
   "&& reload_completed"
   [(set (match_dup 2) (fix:DI (match_dup 1)))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
-  "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 4) (match_dup 3))]
+{
+  operands[3] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+  operands[4] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
@@ -2380,12 +2360,14 @@
 		 (match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
    (clobber (match_scratch:DI 2 "=&f"))
-   (clobber (match_scratch:SI 3 "=&f"))]
+   (clobber (match_scratch:SF 3 "=&f"))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "#"
   "&& reload_completed"
   [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ""
+   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 4) (match_dup 3))]
+{
+  operands[4] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
@@ -2400,8 +2382,10 @@
   "&& reload_completed"
   [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
-  "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 4) (match_dup 3))]
+{
+  operands[3] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+  operands[4] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
@@ -2455,4 +2439,33 @@
    (set_attr "trap_suffix" "sui")])
 
+(define_insn_and_split "*floatsisf2_ieee"
+  [(set (match_operand:SF 0 "register_operand" "=&f")
+	(float:SF (match_operand:SI 1 "memory_operand" "m")))
+   (clobber (match_scratch:DI 2 "=&f"))
+   (clobber (match_scratch:SF 3 "=&f"))]
+  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsisf2"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+	(float:SF (match_operand:SI 1 "memory_operand" "m")))]
+  "TARGET_FP"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+})
+
 (define_insn "*floatdidf_ieee"
   [(set (match_operand:DF 0 "register_operand" "=&f")
@@ -2474,4 +2487,34 @@
    (set_attr "round_suffix" "normal")
    (set_attr "trap_suffix" "sui")])
+
+(define_insn_and_split "*floatsidf2_ieee"
+  [(set (match_operand:DF 0 "register_operand" "=&f")
+	(float:DF (match_operand:SI 1 "memory_operand" "m")))
+   (clobber (match_scratch:DI 2 "=&f"))
+   (clobber (match_scratch:SF 3 "=&f"))]
+  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsidf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+	(float:DF (match_operand:SI 1 "memory_operand" "m")))]
+  "TARGET_FP"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+  operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
 
 (define_expand "floatditf2"
@@ -5102,8 +5145,8 @@
 })
 
-(define_insn "*movsi_nofix"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
-	(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
-  "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
+(define_insn "*movsi"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m")
+	(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ"))]
+  "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
    && (register_operand (operands[0], SImode)
        || reg_or_0_operand (operands[1], SImode))"
@@ -5113,34 +5156,11 @@
    ldah %0,%h1($31)
    ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
-
-(define_insn "*movsi_fix"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
-	(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
-  "TARGET_ABI_OSF && TARGET_FIX
-   && (register_operand (operands[0], SImode)
-       || reg_or_0_operand (operands[1], SImode))"
-  "@
-   bis $31,%r1,%0
-   lda %0,%1($31)
-   ldah %0,%h1($31)
-   ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0
-   ftois %1,%0
-   itofs %1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movsi_nt_vms_nofix"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
-	(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
+   stl %r1,%0"
+  [(set_attr "type" "ilog,iadd,iadd,ild,ist")])
+
+(define_insn "*movsi_nt_vms"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
+	(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ"))]
   "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
-    && !TARGET_FIX
     && (register_operand (operands[0], SImode)
         || reg_or_0_operand (operands[1], SImode))"
@@ -5151,30 +5171,6 @@
    lda %0,%1
    ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
-
-(define_insn "*movsi_nt_vms_fix"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
-	(match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
-  "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
-    && TARGET_FIX
-    && (register_operand (operands[0], SImode)
-        || reg_or_0_operand (operands[1], SImode))"
-  "@
-   bis $31,%1,%0
-   lda %0,%1
-   ldah %0,%h1
-   lda %0,%1
-   ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0
-   ftois %1,%0
-   itofs %1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+   stl %r1,%0"
+  [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist")])
 
 (define_insn "*movhi_nobwx"
Index: trunk/src/gcc/gcc/config/alpha/osf5.h
===================================================================
--- trunk/src/gcc/gcc/config/alpha/osf5.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/alpha/osf5.h	(revision 1469)
@@ -1,4 +1,4 @@
 /* Definitions of target machine for GNU compiler, for DEC Alpha on Tru64 5.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
 
    This file is part of GNU CC.
@@ -20,9 +20,6 @@
 
 /* Tru64 5.1 uses IEEE QUAD format.  */
-/* ??? However, since there is no support for VAX H_floating, we must
-   drop back to a 64-bit long double to avoid a crash looking for the
-   format associated with TFmode.  */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE  (TARGET_FLOAT_VAX ? 64 : 128)
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT	MASK_FP | MASK_FPREGS | MASK_LONG_DOUBLE_128
 
 /* In Tru64 UNIX V5.1, Compaq introduced a new assembler
Index: trunk/src/gcc/gcc/config/arm/arm.c
===================================================================
--- trunk/src/gcc/gcc/config/arm/arm.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/arm/arm.c	(revision 1469)
@@ -278,5 +278,8 @@
 
 /* Nonzero if this chip is an XScale.  */
-int arm_is_xscale = 0;
+int arm_arch_xscale = 0;
+
+/* Nonzero if tuning for XScale  */
+int arm_tune_xscale = 0;
 
 /* Nonzero if this chip is an ARM6 or an ARM7.  */
@@ -688,5 +691,5 @@
   arm_arch5         = (insn_flags & FL_ARCH5) != 0;
   arm_arch5e        = (insn_flags & FL_ARCH5E) != 0;
-  arm_is_xscale     = (insn_flags & FL_XSCALE) != 0;
+  arm_arch_xscale   = (insn_flags & FL_XSCALE) != 0;
 
   arm_ld_sched      = (tune_flags & FL_LDSCHED) != 0;
@@ -695,4 +698,5 @@
   arm_is_6_or_7     = (((tune_flags & (FL_MODE26 | FL_MODE32))
 		       && !(tune_flags & FL_ARCH4))) != 0;
+  arm_tune_xscale   = (tune_flags & FL_XSCALE) != 0;
 
   /* Default value for floating point code... if no co-processor
@@ -766,5 +770,5 @@
     arm_constant_limit = 1;
   
-  if (arm_is_xscale)
+  if (arm_arch_xscale)
     arm_constant_limit = 2;
 
@@ -2957,5 +2961,5 @@
   /* Some true dependencies can have a higher cost depending
      on precisely how certain input operands are used.  */
-  if (arm_is_xscale
+  if (arm_tune_xscale
       && REG_NOTE_KIND (link) == 0
       && recog_memoized (insn) < 0
@@ -3789,4 +3793,10 @@
 	reg1 = REGNO (XEXP (b, 0));
 
+      /* Don't accept any offset that will require multiple instructions to handle,
+	 since this would cause the arith_adjacentmem pattern to output an overlong
+	 sequence.  */
+      if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
+	return 0;
+      
       return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
     }
@@ -4400,5 +4410,5 @@
      As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
      for counts of 3 or 4 regs.  */
-  if (arm_is_xscale && count <= 2 && ! optimize_size)
+  if (arm_tune_xscale && count <= 2 && ! optimize_size)
     {
       rtx seq;
@@ -4467,5 +4477,5 @@
   /* See arm_gen_load_multiple for discussion of
      the pros/cons of ldm/stm usage for XScale.  */
-  if (arm_is_xscale && count <= 2 && ! optimize_size)
+  if (arm_tune_xscale && count <= 2 && ! optimize_size)
     {
       rtx seq;
Index: trunk/src/gcc/gcc/config/arm/arm.h
===================================================================
--- trunk/src/gcc/gcc/config/arm/arm.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/arm/arm.h	(revision 1469)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for ARM.
    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002 Free Software Foundation, Inc.
+   2001, 2002, 2004 Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
@@ -574,5 +574,8 @@
 
 /* Nonzero if this chip is an XScale.  */
-extern int arm_is_xscale;
+extern int arm_arch_xscale;
+
+/* Nonzero if tuning for XScale  */
+extern int arm_tune_xscale;
 
 /* Nonzero if this chip is an ARM6 or an ARM7.  */
@@ -707,5 +710,5 @@
 
 /* Make strings word-aligned so strcpy from constants will be faster.  */
-#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2)
+#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_arch_xscale ? 1 : 2)
     
 #define CONSTANT_ALIGNMENT(EXP, ALIGN)				\
@@ -1778,11 +1781,17 @@
    FNADDR is an RTX for the address of the function's pure code.
    CXT is an RTX for the static chain value for the function.  */
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)  					\
-{											\
-  emit_move_insn									\
-    (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 8 : 16)), CXT);		\
-  emit_move_insn									\
-    (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 12 : 20)),	FNADDR);	\
+#ifndef INITIALIZE_TRAMPOLINE
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)			\
+{									\
+  emit_move_insn (gen_rtx_MEM (SImode,					\
+			       plus_constant (TRAMP,			\
+					      TARGET_ARM ? 8 : 16)),	\
+		  CXT);							\
+  emit_move_insn (gen_rtx_MEM (SImode,					\
+			       plus_constant (TRAMP,			\
+					      TARGET_ARM ? 12 : 20)),	\
+		  FNADDR);						\
 }
+#endif
 
 
@@ -2013,8 +2022,15 @@
 		goto LABEL;						\
 	    }								\
-	  /* NASTY: Since this limits the addressing of unsigned	\
-	     byte loads.  */						\
-	  range = ((MODE) == HImode || (MODE) == QImode)		\
-	    ? (arm_arch4 ? 256 : 4095) : 4096;				\
+  	  /* XXX For ARM v4 we may be doing a sign-extend operation	\
+	     during the load, but that has a restricted addressing	\
+	     range and we are unable to tell here whether that is the	\
+	     case.  To be safe we restrict all loads to that		\
+	     range.  */							\
+          if (arm_arch4)						\
+	    range = (mode == HImode || mode == QImode) ? 256 : 4096;	\
+	  else if (mode == HImode)					\
+	    range = 4095;						\
+	  else								\
+	    range = 4096;						\
 	  if (code == CONST_INT && INTVAL (INDEX) < range		\
 	      && INTVAL (INDEX) > -range)				\
@@ -2039,5 +2055,5 @@
 	   && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0)))			\
     goto LABEL;								\
-  else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed		\
+  else if (reload_completed						\
 	   && (GET_CODE (X) == LABEL_REF				\
 	       || (GET_CODE (X) == CONST				\
@@ -2190,4 +2206,5 @@
     }									\
   else if (GET_MODE_CLASS (MODE) != MODE_FLOAT				\
+	   && GET_MODE_SIZE (mode) == 4					\
 	   && GET_CODE (X) == SYMBOL_REF				\
 	   && CONSTANT_POOL_ADDRESS_P (X)				\
@@ -2334,5 +2351,5 @@
 
 #undef  MOVE_RATIO
-#define MOVE_RATIO (arm_is_xscale ? 4 : 2)
+#define MOVE_RATIO (arm_arch_xscale ? 4 : 2)
 
 /* Define if operations between registers always perform the operation
Index: trunk/src/gcc/gcc/config/arm/arm.md
===================================================================
--- trunk/src/gcc/gcc/config/arm/arm.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/arm/arm.md	(revision 1469)
@@ -1,5 +1,5 @@
 ;;- Machine description for ARM for GNU compiler
 ;;  Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
-;;  2001, 2002  Free Software Foundation, Inc.
+;;  2001, 2002, 2004  Free Software Foundation, Inc.
 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
 ;;  and Martin Simmons (@harleqn.co.uk).
@@ -123,5 +123,5 @@
 ;; Operand number of an input operand that is shifted.  Zero if the
 ;; given instruction does not shift one of its input operands.
-(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_is_xscale")))
+(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
 (define_attr "shift" "" (const_int 0))
 
@@ -1190,5 +1190,5 @@
    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
 	(mult:SI (match_dup 2) (match_dup 1)))]
-  "TARGET_ARM && !arm_is_xscale"
+  "TARGET_ARM && !arm_arch_xscale"
   "mul%?s\\t%0, %2, %1"
   [(set_attr "conds" "set")
@@ -1203,5 +1203,5 @@
 			 (const_int 0)))
    (clobber (match_scratch:SI 0 "=&r,&r"))]
-  "TARGET_ARM && !arm_is_xscale"
+  "TARGET_ARM && !arm_arch_xscale"
   "mul%?s\\t%0, %2, %1"
   [(set_attr "conds" "set")
@@ -1234,5 +1234,5 @@
 	(plus:SI (mult:SI (match_dup 2) (match_dup 1))
 		 (match_dup 3)))]
-  "TARGET_ARM && !arm_is_xscale"
+  "TARGET_ARM && !arm_arch_xscale"
   "mla%?s\\t%0, %2, %1, %3"
   [(set_attr "conds" "set")
@@ -1249,5 +1249,5 @@
 	 (const_int 0)))
    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
-  "TARGET_ARM && !arm_is_xscale"
+  "TARGET_ARM && !arm_arch_xscale"
   "mla%?s\\t%0, %2, %1, %3"
   [(set_attr "conds" "set")
@@ -1343,5 +1343,5 @@
 		 (sign_extend:SI
 		  (match_operand:HI 2 "s_register_operand" "r"))))]
-  "TARGET_ARM && arm_is_xscale"
+  "TARGET_ARM && arm_arch_xscale"
   "smulbb%?\\t%0, %1, %2"
   [(set_attr "type" "mult")]
@@ -1355,5 +1355,5 @@
 			  (sign_extend:SI
 			   (match_operand:HI 3 "s_register_operand" "r")))))]
-  "TARGET_ARM && arm_is_xscale"
+  "TARGET_ARM && arm_arch_xscale"
   "smlabb%?\\t%0, %2, %3, %1"
   [(set_attr "type" "mult")]
@@ -1368,5 +1368,5 @@
 		   (sign_extend:DI
 		    (match_operand:HI 3 "s_register_operand" "r")))))]
-  "TARGET_ARM && arm_is_xscale"
+  "TARGET_ARM && arm_arch_xscale"
   "smlalbb%?\\t%Q0, %R0, %2, %3"
 [(set_attr "type" "mult")])
@@ -4599,6 +4599,6 @@
 
 (define_insn "*thumb_movhi_insn"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l, m,*r,*h,l")
-	(match_operand:HI 1 "general_operand"       "l,mn,l,*h,*r,I"))]
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
+	(match_operand:HI 1 "general_operand"       "l,m,l,*h,*r,I"))]
   "TARGET_THUMB
    && (   register_operand (operands[0], HImode)
@@ -4632,6 +4632,5 @@
     }"
   [(set_attr "length" "2,4,2,2,2,2")
-   (set_attr "type" "*,load,store1,*,*,*")
-   (set_attr "pool_range" "*,64,*,*,*,*")]
+   (set_attr "type" "*,load,store1,*,*,*")]
 )
 
Index: trunk/src/gcc/gcc/config/arm/elf.h
===================================================================
--- trunk/src/gcc/gcc/config/arm/elf.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/arm/elf.h	(revision 1469)
@@ -156,14 +156,4 @@
 
 
-#undef  ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_OUTPUT_ALIGNED_COMMON(STREAM, NAME, SIZE, ALIGN)	\
-  do								\
-    {								\
-      fprintf (STREAM, "\t.comm\t");				\
-      assemble_name (STREAM, NAME);				\
-      fprintf (STREAM, ", %d, %d\n", SIZE, ALIGN);		\
-    }								\
-  while (0)
-
 /* For PIC code we need to explicitly specify (PLT) and (GOT) relocs.  */
 #define NEED_PLT_RELOC	flag_pic
Index: trunk/src/gcc/gcc/config/arm/linux-elf.h
===================================================================
--- trunk/src/gcc/gcc/config/arm/linux-elf.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/arm/linux-elf.h	(revision 1469)
@@ -34,4 +34,6 @@
 #undef  TARGET_DEFAULT
 #define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
+
+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
 
 #define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p"
Index: trunk/src/gcc/gcc/config/cris/cris.c
===================================================================
--- trunk/src/gcc/gcc/config/cris/cris.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/cris/cris.c	(revision 1469)
@@ -1,4 +1,4 @@
 /* Definitions for GCC.  Part of the machine description for CRIS.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Axis Communications.  Written by Hans-Peter Nilsson.
 
@@ -313,5 +313,8 @@
 }
 
-/* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN.  */
+/* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN.
+   By the name, you might think we should include MULT.  We don't because
+   it doesn't accept the same addressing modes as the others (ony
+   registers) and there's also the problem of handling TARGET_MUL_BUG.  */
 
 int
@@ -497,5 +500,9 @@
 
     case MULT:
-      return "mul";
+      /* This function is for retrieving a part of an instruction name for
+	 an operator, for immediate output.  If that ever happens for
+	 MULT, we need to apply TARGET_MUL_BUG in the caller.  Make sure
+	 we notice.  */
+      abort ();
       break;
 
@@ -1402,4 +1409,21 @@
       return;
 
+    case '!':
+      /* Output directive for alignment padded with "nop" insns.
+	 Optimizing for size, it's plain 4-byte alignment, otherwise we
+	 align the section to a cache-line (32 bytes) and skip at max 2
+	 bytes, i.e. we skip if it's the last insn on a cache-line.  The
+	 latter is faster by a small amount (for two test-programs 99.6%
+	 and 99.9%) and larger by a small amount (ditto 100.1% and
+	 100.2%).  This is supposed to be the simplest yet performance-
+	 wise least intrusive way to make sure the immediately following
+	 (supposed) muls/mulu insn isn't located at the end of a
+	 cache-line.  */
+      if (TARGET_MUL_BUG)
+	fputs (optimize_size
+	       ? ".p2alignw 2,0x050f\n\t"
+	       : ".p2alignw 5,0x050f,2\n\t", file);
+      return;
+
     case 'H':
       /* Print high (most significant) part of something.  */
@@ -2636,8 +2660,22 @@
       const char *name = XSTR (XEXP (DECL_RTL (funcdecl), 0), 0);
 
+      /* We have no other relative (to either PC or GOT) reloc than one
+	 that requests a PLT entry.  Since we don't set up the GOT
+	 register, the jump absolutely must not be redirected through a
+	 PLT entry.  We manage anyway by going through a local symbol.
+	 This depends on the assembler to not short-circuit equalities
+	 set by the ".set" directive (at least not for PIC relocs) and
+	 on the linker to direct R_CRIS_32_PLT_PCREL relocs *directly*
+	 to the symbol for local symbols, instead of through a PLT
+	 entry.  */
       name = (* targetm.strip_name_encoding) (name);
-      fprintf (stream, "add.d ");
+      fprintf (stream, "\tadd.d ");
       assemble_name (stream, name);
-      fprintf (stream, "%s,$pc\n", CRIS_PLT_PCOFFSET_SUFFIX);
+      fprintf (stream, "..xth%s,$pc\n", CRIS_PLT_PCOFFSET_SUFFIX);
+      fprintf (stream, "\t.set ");
+      assemble_name (stream, name);
+      fprintf (stream, "..xth,");
+      assemble_name (stream, name);
+      fprintf (stream, "\n");
     }
   else
Index: trunk/src/gcc/gcc/config/cris/cris.h
===================================================================
--- trunk/src/gcc/gcc/config/cris/cris.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/cris/cris.h	(revision 1469)
@@ -171,7 +171,15 @@
 #define CC1PLUS_SPEC ""
 
+#ifdef HAVE_AS_MUL_BUG_ABORT_OPTION
+#define MAYBE_AS_NO_MUL_BUG_ABORT \
+ "%{mno-mul-bug-workaround:-no-mul-bug-abort} "
+#else
+#define MAYBE_AS_NO_MUL_BUG_ABORT
+#endif
+
 /* Override previous definitions (linux.h).  */
 #undef ASM_SPEC
 #define ASM_SPEC \
+ MAYBE_AS_NO_MUL_BUG_ABORT \
  "%{v:-v}\
   %(asm_subtarget)"
@@ -332,6 +340,32 @@
 #define TARGET_AVOID_GOTPLT (target_flags & TARGET_MASK_AVOID_GOTPLT)
 
+/* Whether or not to work around multiplication instruction hardware bug
+   when generating code for models where it may be present.  From the
+   trouble report for Etrax 100 LX: "A multiply operation may cause
+   incorrect cache behaviour under some specific circumstances. The
+   problem can occur if the instruction following the multiply instruction
+   causes a cache miss, and multiply operand 1 (source operand) bits
+   [31:27] matches the logical mapping of the mode register address
+   (0xb0....), and bits [9:2] of operand 1 matches the TLB register
+   address (0x258-0x25f).  There is such a mapping in kernel mode or when
+   the MMU is off.  Normally there is no such mapping in user mode, and
+   the problem will therefore probably not occur in Linux user mode
+   programs."
+
+   We have no sure-fire way to know from within GCC that we're compiling a
+   user program.  For example, -fpic/PIC is used in libgcc which is linked
+   into the kernel.  However, the workaround option -mno-mul-bug can be
+   safely used per-package when compiling programs.  The same goes for
+   general user-only libraries such as glibc, since there's no user-space
+   driver-like program that gets a mapping of I/O registers (all on the
+   same page, including the TLB registers).  */
+#define TARGET_MASK_MUL_BUG 16384
+#define TARGET_MUL_BUG (target_flags & TARGET_MASK_MUL_BUG)
+
 #define TARGET_SWITCHES							\
  {									\
+  {"mul-bug-workaround",		 TARGET_MASK_MUL_BUG,		\
+   N_("Work around bug in multiplication instruction")},		\
+  {"no-mul-bug-workaround",		-TARGET_MASK_MUL_BUG, ""},	\
   /* No "no-etrax" as it does not really imply any model.		\
      On the other hand, "etrax" implies the common (and large)		\
@@ -411,5 +445,5 @@
  (TARGET_MASK_SIDE_EFFECT_PREFIXES + TARGET_MASK_STACK_ALIGN \
   + TARGET_MASK_CONST_ALIGN + TARGET_MASK_DATA_ALIGN \
-  + TARGET_MASK_PROLOGUE_EPILOGUE)
+  + TARGET_MASK_PROLOGUE_EPILOGUE + TARGET_MASK_MUL_BUG)
 #endif
 
@@ -1623,5 +1657,6 @@
 
 /* For delay-slot handling.  */
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#')
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE)	\
+ ((CODE) == '#' || (CODE) == '!')
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)	\
Index: trunk/src/gcc/gcc/config/cris/cris.md
===================================================================
--- trunk/src/gcc/gcc/config/cris/cris.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/cris/cris.md	(revision 1469)
@@ -2504,6 +2504,9 @@
 	 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   "TARGET_HAS_MUL_INSNS"
-  "mulu.w %2,%0"
-  [(set_attr "slottable" "yes")
+  "%!mulu.w %2,%0"
+  [(set (attr "slottable")
+	(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
+		      (const_string "no")
+		      (const_string "yes")))
    ;; Just N unusable here, but let's be safe.
    (set_attr "cc" "clobber")])
@@ -2515,6 +2518,9 @@
 	 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
   "TARGET_HAS_MUL_INSNS"
-  "mulu.b %2,%0"
-  [(set_attr "slottable" "yes")
+  "%!mulu.b %2,%0"
+  [(set (attr "slottable")
+	(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
+		      (const_string "no")
+		      (const_string "yes")))
    ;; Not exactly sure, but let's be safe.
    (set_attr "cc" "clobber")])
@@ -2531,6 +2537,9 @@
 		 (match_operand:SI 2 "register_operand" "r")))]
   "TARGET_HAS_MUL_INSNS"
-  "muls.d %2,%0"
-  [(set_attr "slottable" "yes")
+  "%!muls.d %2,%0"
+  [(set (attr "slottable")
+	(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
+		      (const_string "no")
+		      (const_string "yes")))
    ;; Just N unusable here, but let's be safe.
    (set_attr "cc" "clobber")])
@@ -2547,6 +2556,9 @@
 	 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
   "TARGET_HAS_MUL_INSNS"
-  "muls.b %2,%0"
-  [(set_attr "slottable" "yes")
+  "%!muls.b %2,%0"
+  [(set (attr "slottable")
+	(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
+		      (const_string "no")
+		      (const_string "yes")))
    (set_attr "cc" "clobber")])
 
@@ -2557,6 +2569,9 @@
 	 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   "TARGET_HAS_MUL_INSNS"
-  "muls.w %2,%0"
-  [(set_attr "slottable" "yes")
+  "%!muls.w %2,%0"
+  [(set (attr "slottable")
+	(if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
+		      (const_string "no")
+		      (const_string "yes")))
    ;; Just N unusable here, but let's be safe.
    (set_attr "cc" "clobber")])
@@ -2574,5 +2589,5 @@
 	 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
   "TARGET_HAS_MUL_INSNS"
-  "muls.d %2,%M0\;move $mof,%H0")
+  "%!muls.d %2,%M0\;move $mof,%H0")
 
 (define_insn "umulsidi3"
@@ -2582,5 +2597,5 @@
 	 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
   "TARGET_HAS_MUL_INSNS"
-  "mulu.d %2,%M0\;move $mof,%H0")
+  "%!mulu.d %2,%M0\;move $mof,%H0")
 
 ;; This pattern would probably not be needed if we add "mof" in its own
@@ -2601,5 +2616,5 @@
    (clobber (match_scratch:SI 3 "=X,1,1"))]
   "TARGET_HAS_MUL_INSNS"
-  "muls.d %2,%1\;move $mof,%0"
+  "%!muls.d %2,%1\;move $mof,%0"
   [(set_attr "cc" "clobber")])
 
@@ -2614,5 +2629,5 @@
    (clobber (match_scratch:SI 3 "=X,1,1"))]
   "TARGET_HAS_MUL_INSNS"
-  "mulu.d %2,%1\;move $mof,%0"
+  "%!mulu.d %2,%1\;move $mof,%0"
   [(set_attr "cc" "clobber")])
 
@@ -2721,15 +2736,17 @@
 (define_insn "*andsi_movu"
   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
-	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%r,Q>,m")
+	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%r,Q,To")
 		(match_operand:SI 2 "const_int_operand" "n,n,n")))]
-  "INTVAL (operands[2]) == 255 || INTVAL (operands[2]) == 65535"
+  "(INTVAL (operands[2]) == 255 || INTVAL (operands[2]) == 65535)
+   && (GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1]))"
   "movu.%z2 %1,%0"
   [(set_attr "slottable" "yes,yes,no")])
 
 (define_insn "*andsi_clear"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,Q>,Q>,m,m")
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,Q,Q,To,To")
 	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
 		(match_operand:SI 2 "const_int_operand" "P,n,P,n,P,n")))]
-  "INTVAL (operands[2]) == -65536 || INTVAL (operands[2]) == -256"
+  "(INTVAL (operands[2]) == -65536 || INTVAL (operands[2]) == -256)
+   && (GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0]))"
   "@
    cLear.b %0
@@ -2810,25 +2827,15 @@
 (define_insn "*andhi_movu"
   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
-	(and:HI (match_operand:HI 1 "nonimmediate_operand" "r,Q>,m")
+	(and:HI (match_operand:HI 1 "nonimmediate_operand" "r,Q,To")
 		(const_int 255)))]
-  ""
+  "GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1])"
   "mOvu.b %1,%0"
   [(set_attr "slottable" "yes,yes,no")])
 
-(define_insn "*andhi_clear_signed"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q>,m")
+(define_insn "*andhi_clear"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q,To")
 	(and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
 		(const_int -256)))]
-  ""
-  "cLear.b %0"
-  [(set_attr "slottable" "yes,yes,no")
-   (set_attr "cc" "none")])
-
-;; FIXME: Either this or the pattern above should be redundant.
-(define_insn "*andhi_clear_unsigned"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q>,m")
-	(and:HI (match_operand:HI 1 "nonimmediate_operand" "0,0,0")
-		(const_int 65280)))]
-  ""
+  "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
   "cLear.b %0"
   [(set_attr "slottable" "yes,yes,no")
Index: trunk/src/gcc/gcc/config/cris/mulsi3.asm
===================================================================
--- trunk/src/gcc/gcc/config/cris/mulsi3.asm	(revision 1466)
+++ trunk/src/gcc/gcc/config/cris/mulsi3.asm	(revision 1469)
@@ -83,6 +83,11 @@
 ___Mul:
 #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
-	ret
+;; Can't have the mulu.d last on a cache-line (in the delay-slot of the
+;; "ret"), due to hardware bug.  See documentation for -mmul-bug-workaround.
+;; Not worthwhile to conditionalize here.
+	.p2alignw 2,0x050f
 	mulu.d $r11,$r10
+	ret
+	nop
 #else
 	move.d $r10,$r12
Index: trunk/src/gcc/gcc/config/darwin.h
===================================================================
--- trunk/src/gcc/gcc/config/darwin.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/darwin.h	(revision 1469)
@@ -193,5 +193,5 @@
     %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%G %L}} \
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} %{F*} \
-    %{!--help:%{!no-c++filt|c++filt:| c++filt3 }} }}}}}}}}"
+    %{!--help:%{!no-c++filt|c++filt:| c++filt }} }}}}}}}}"
 
 /* Please keep the random linker options in alphabetical order (modulo
Index: trunk/src/gcc/gcc/config/i386/i386.md
===================================================================
--- trunk/src/gcc/gcc/config/i386/i386.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/i386/i386.md	(revision 1469)
@@ -1695,9 +1695,9 @@
    (set_attr "mode" "QI")])
 
-(define_insn "*movsi_insv_1_rex64"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
+(define_insn "movdi_insv_1_rex64"
+  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
 			 (const_int 8)
 			 (const_int 8))
-	(match_operand:SI 1 "nonmemory_operand" "Qn"))]
+	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
   "TARGET_64BIT"
   "mov{b}\t{%b1, %h0|%h0, %b1}"
@@ -12447,8 +12447,8 @@
 
 (define_expand "insv"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
-			 (match_operand:SI 1 "immediate_operand" "")
-			 (match_operand:SI 2 "immediate_operand" ""))
-        (match_operand:SI 3 "register_operand" ""))]
+  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
+		      (match_operand 1 "immediate_operand" "")
+		      (match_operand 2 "immediate_operand" ""))
+        (match_operand 3 "register_operand" ""))]
   ""
 {
@@ -12461,4 +12461,11 @@
   if (! register_operand (operands[0], VOIDmode))
     FAIL;
+
+  if (TARGET_64BIT)
+    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
+  else
+    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
+
+  DONE;
 })
 
Index: trunk/src/gcc/gcc/config/m68k/m68k.c
===================================================================
--- trunk/src/gcc/gcc/config/m68k/m68k.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/m68k/m68k.c	(revision 1469)
@@ -1748,4 +1748,5 @@
 #endif
     case NOTB :
+      CC_STATUS_INIT;
       operands[1] = GEN_INT (i ^ 0xff);
 #if defined (MOTOROLA) && !defined (CRDS)
@@ -1755,4 +1756,5 @@
 #endif	 
     case NOTW :
+      CC_STATUS_INIT;
       operands[1] = GEN_INT (i ^ 0xffff);
 #if defined (MOTOROLA) && !defined (CRDS)
@@ -1762,4 +1764,5 @@
 #endif	 
     case NEGW :
+      CC_STATUS_INIT;
 #if defined (MOTOROLA) && !defined (CRDS)
       return "moveq%.l %#-128,%0\n\tneg%.w %0";
Index: trunk/src/gcc/gcc/config/mips/mips.md
===================================================================
--- trunk/src/gcc/gcc/config/mips/mips.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/mips/mips.md	(revision 1469)
@@ -106,5 +106,5 @@
    (cond [(eq_attr "type" "branch")
           (cond [(lt (abs (minus (match_dup 1) (plus (pc) (const_int 4))))
-                     (const_int 131072))
+                     (const_int 65536))
                  (const_int 4)
 		 (ne (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC")
@@ -9652,5 +9652,5 @@
 	      (lt (abs (minus (match_dup 0)
 			      (plus (pc) (const_int 4))))
-		  (const_int 131072)))
+		  (const_int 65536)))
 	 (const_int 4) (const_int 16)))])
 
Index: trunk/src/gcc/gcc/config/pa/pa.h
===================================================================
--- trunk/src/gcc/gcc/config/pa/pa.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/pa/pa.h	(revision 1469)
@@ -997,5 +997,5 @@
 #define TRAMPOLINE_TEMPLATE(FILE) 					\
   {									\
-    if (! TARGET_64BIT)							\
+    if (!TARGET_64BIT)							\
       {									\
 	fputs ("\tldw	36(%r22),%r21\n", FILE);			\
@@ -1007,8 +1007,18 @@
 	fputs ("\tldw	4(%r21),%r19\n", FILE);				\
 	fputs ("\tldw	0(%r21),%r21\n", FILE);				\
-	fputs ("\tldsid	(%r21),%r1\n", FILE);				\
-	fputs ("\tmtsp	%r1,%sr0\n", FILE);				\
-	fputs ("\tbe	0(%sr0,%r21)\n", FILE);				\
-	fputs ("\tldw	40(%r22),%r29\n", FILE);			\
+	if (TARGET_PA_20)						\
+	  {								\
+	    fputs ("\tbve	(%r21)\n", FILE);			\
+	    fputs ("\tldw	40(%r22),%r29\n", FILE);		\
+	    fputs ("\t.word	0\n", FILE);				\
+	    fputs ("\t.word	0\n", FILE);				\
+	  }								\
+	else								\
+	  {								\
+	    fputs ("\tldsid	(%r21),%r1\n", FILE);			\
+	    fputs ("\tmtsp	%r1,%sr0\n", FILE);			\
+	    fputs ("\tbe	0(%sr0,%r21)\n", FILE);			\
+	    fputs ("\tldw	40(%r22),%r29\n", FILE);		\
+	  }								\
 	fputs ("\t.word	0\n", FILE);					\
 	fputs ("\t.word	0\n", FILE);					\
@@ -1033,14 +1043,19 @@
   }
 
-/* Length in units of the trampoline for entering a nested function.
-
-   Flush the cache entries corresponding to the first and last addresses
-   of the trampoline.  This is necessary as the trampoline may cross two
-   cache lines.
-
-   If the code part of the trampoline ever grows to > 32 bytes, then it
-   will become necessary to hack on the cacheflush pattern in pa.md.  */
+/* Length in units of the trampoline for entering a nested function.  */
 
 #define TRAMPOLINE_SIZE (TARGET_64BIT ? 72 : 52)
+
+/* Length in units of the trampoline instruction code.  */
+
+#define TRAMPOLINE_CODE_SIZE (TARGET_64BIT ? 24 : (TARGET_PA_20 ? 32 : 40))
+
+/* Minimum length of a cache line.  A length of 16 will work on all
+   PA-RISC processors.  All PA 1.1 processors have a cache line of
+   32 bytes.  Most but not all PA 2.0 processors have a cache line
+   of 64 bytes.  As cache flushes are expensive and we don't support
+   PA 1.0, we use a minimum length of 32.  */
+
+#define MIN_CACHELINE_SIZE 32
 
 /* Emit RTL insns to initialize the variable parts of a trampoline.
@@ -1052,53 +1067,83 @@
    Move the trampoline address to trampoline template at offset 44.
    Move r19 to trampoline template at offset 48.  The latter two
-   words create a plabel for the indirect call to the trampoline.  */
+   words create a plabel for the indirect call to the trampoline.
+
+   A similar sequence is used for the 64-bit port but the plabel is
+   at the beginning of the trampoline.
+
+   Finally, the cache entries for the trampoline code are flushed.
+   This is necessary to ensure that the trampoline instruction sequence
+   is written to memory prior to any attempts at prefetching the code
+   sequence.  */
 
 #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) 			\
 {									\
-  if (! TARGET_64BIT)							\
+  rtx start_addr = gen_reg_rtx (Pmode);					\
+  rtx end_addr = gen_reg_rtx (Pmode);					\
+  rtx line_length = gen_reg_rtx (Pmode);				\
+  rtx tmp;								\
+									\
+  if (!TARGET_64BIT)							\
     {									\
-      rtx start_addr, end_addr;						\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 36));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp), (FNADDR));		\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 40));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp), (CXT));			\
 									\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 36));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (FNADDR));	\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 40));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (CXT));		\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 44));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (TRAMP));	\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 48));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr),			\
+      /* Create a fat pointer for the trampoline.  */			\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 44));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp), (TRAMP));		\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 48));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp),				\
 		      gen_rtx_REG (Pmode, 19));				\
+									\
       /* fdc and fic only use registers for the address to flush,	\
-	 they do not accept integer displacements.  */ 			\
-      start_addr = force_reg (Pmode, (TRAMP));				\
-      end_addr = force_reg (Pmode, plus_constant ((TRAMP), 32));	\
-      emit_insn (gen_dcacheflush (start_addr, end_addr));		\
-      end_addr = force_reg (Pmode, plus_constant (start_addr, 32));	\
-      emit_insn (gen_icacheflush (start_addr, end_addr, start_addr,	\
-				  gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));\
+	 they do not accept integer displacements.  We align the	\
+	 start and end addresses to the beginning of their respective	\
+	 cache lines to minimize the number of lines flushed.  */	\
+      tmp = force_reg (Pmode, (TRAMP));					\
+      emit_insn (gen_andsi3 (start_addr, tmp,				\
+			     GEN_INT (-MIN_CACHELINE_SIZE)));		\
+      tmp = force_reg (Pmode,						\
+		       plus_constant (tmp, TRAMPOLINE_CODE_SIZE - 1));	\
+      emit_insn (gen_andsi3 (end_addr, tmp,				\
+			     GEN_INT (-MIN_CACHELINE_SIZE)));		\
+      emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));	\
+      emit_insn (gen_dcacheflush (start_addr, end_addr, line_length));	\
+      emit_insn (gen_icacheflush (start_addr, end_addr, line_length,	\
+				  gen_reg_rtx (Pmode),			\
+				  gen_reg_rtx (Pmode)));		\
     }									\
   else									\
     {									\
-      rtx start_addr, end_addr;						\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 56));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp), (FNADDR));		\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 64));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp), (CXT));			\
 									\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 56));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (FNADDR));	\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 64));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (CXT));		\
       /* Create a fat pointer for the trampoline.  */			\
-      end_addr = force_reg (Pmode, plus_constant ((TRAMP), 32));	\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 16));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr), end_addr);	\
-      end_addr = gen_rtx_REG (Pmode, 27);				\
-      start_addr = memory_address (Pmode, plus_constant ((TRAMP), 24));	\
-      emit_move_insn (gen_rtx_MEM (Pmode, start_addr), end_addr);	\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 16));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp),				\
+		      force_reg (Pmode, plus_constant ((TRAMP), 32)));	\
+      tmp = memory_address (Pmode, plus_constant ((TRAMP), 24));	\
+      emit_move_insn (gen_rtx_MEM (Pmode, tmp),				\
+		      gen_rtx_REG (Pmode, 27));				\
+									\
       /* fdc and fic only use registers for the address to flush,	\
-	 they do not accept integer displacements.  */ 			\
-      start_addr = force_reg (Pmode, (TRAMP));				\
-      end_addr = force_reg (Pmode, plus_constant ((TRAMP), 32));	\
-      emit_insn (gen_dcacheflush (start_addr, end_addr));		\
-      end_addr = force_reg (Pmode, plus_constant (start_addr, 32));	\
-      emit_insn (gen_icacheflush (start_addr, end_addr, start_addr,	\
-				  gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));\
+	 they do not accept integer displacements.  We align the	\
+	 start and end addresses to the beginning of their respective	\
+	 cache lines to minimize the number of lines flushed.  */	\
+      tmp = force_reg (Pmode, plus_constant ((TRAMP), 32));		\
+      emit_insn (gen_anddi3 (start_addr, tmp,				\
+			     GEN_INT (-MIN_CACHELINE_SIZE)));		\
+      tmp = force_reg (Pmode,						\
+		       plus_constant (tmp, TRAMPOLINE_CODE_SIZE - 1));	\
+      emit_insn (gen_anddi3 (end_addr, tmp,				\
+			     GEN_INT (-MIN_CACHELINE_SIZE)));		\
+      emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));	\
+      emit_insn (gen_dcacheflush (start_addr, end_addr, line_length));	\
+      emit_insn (gen_icacheflush (start_addr, end_addr, line_length,	\
+				  gen_reg_rtx (Pmode),			\
+				  gen_reg_rtx (Pmode)));		\
     }									\
 }
Index: trunk/src/gcc/gcc/config/pa/pa.md
===================================================================
--- trunk/src/gcc/gcc/config/pa/pa.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/pa/pa.md	(revision 1469)
@@ -4397,8 +4397,18 @@
   "
 {
-  if (! register_operand (operands[1], DImode)
-      || ! register_operand (operands[2], DImode))
-    /* Let GCC break this into word-at-a-time operations.  */
-    FAIL;
+  if (TARGET_64BIT)
+    {
+      /* One operand must be a register operand.  */
+      if (!register_operand (operands[1], DImode)
+	  && !register_operand (operands[2], DImode))
+	FAIL;
+    }
+  else
+    {
+      /* Both operands must be register operands.  */
+      if (!register_operand (operands[1], DImode)
+	  || !register_operand (operands[2], DImode))
+	FAIL;
+    }
 }")
 
@@ -7779,27 +7789,56 @@
 }")
 
-;; Flush the I and D cache line found at the address in operand 0.
+;; Flush the I and D cache lines from the start address (operand0)
+;; to the end address (operand1).  No lines are flushed if the end
+;; address is less than the start address (unsigned).
+;;
+;; Because the range of memory flushed is variable and the size of
+;; a MEM can only be a CONST_INT, the patterns specify that they
+;; perform an unspecified volatile operation on all memory.
+;;
+;; The address range for an icache flush must lie within a single
+;; space on targets with non-equivalent space registers.
+;;
 ;; This is used by the trampoline code for nested functions.
-;; So long as the trampoline itself is less than 32 bytes this
-;; is sufficient.
-
+;;
+;; Operand 0 contains the start address.
+;; Operand 1 contains the end address.
+;; Operand 2 contains the line length to use.
+;; Operands 3 and 4 (icacheflush) are clobbered scratch registers.
 (define_insn "dcacheflush"
-  [(unspec_volatile [(const_int 1)] 0)
-   (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
-   (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
-  ""
-  "fdc 0(%0)\;fdc 0(%1)\;sync"
+  [(const_int 1)
+   (unspec_volatile [(mem:BLK (scratch))] 0)
+   (use (match_operand 0 "pmode_register_operand" "r"))
+   (use (match_operand 1 "pmode_register_operand" "r"))
+   (use (match_operand 2 "pmode_register_operand" "r"))
+   (clobber (match_scratch 3 "=&0"))]
+  ""
+  "*
+{
+  if (TARGET_64BIT)
+    return \"cmpb,*<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
+  else
+    return \"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
+}"
   [(set_attr "type" "multi")
    (set_attr "length" "12")])
 
 (define_insn "icacheflush"
-  [(unspec_volatile [(const_int 2)] 0)
-   (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
-   (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
+  [(const_int 2)
+   (unspec_volatile [(mem:BLK (scratch))] 0)
+   (use (match_operand 0 "pmode_register_operand" "r"))
+   (use (match_operand 1 "pmode_register_operand" "r"))
    (use (match_operand 2 "pmode_register_operand" "r"))
    (clobber (match_operand 3 "pmode_register_operand" "=&r"))
-   (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
-  ""
-  "mfsp %%sr0,%4\;ldsid (%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
+   (clobber (match_operand 4 "pmode_register_operand" "=&r"))
+   (clobber (match_scratch 5 "=&0"))]
+  ""
+  "*
+{
+  if (TARGET_64BIT)
+    return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,*<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
+  else
+    return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
+}"
   [(set_attr "type" "multi")
    (set_attr "length" "52")])
Index: trunk/src/gcc/gcc/config/pa/pa64-hpux.h
===================================================================
--- trunk/src/gcc/gcc/config/pa/pa64-hpux.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/pa/pa64-hpux.h	(revision 1469)
@@ -44,14 +44,33 @@
 #endif
 
-/* Like the default, except no -lg.  */
+/* Profiling support is only provided in libc.a.  However, libprof and
+   libgprof are only available in shared form on HP-UX 11.00.  We use
+   the shared form if we are using the GNU linker or an archive form
+   isn't available.  We also usually need to link with libdld and it's
+   only available in shared form.  */
 #undef LIB_SPEC
+#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GNU_LD)
 #define LIB_SPEC \
   "%{!shared:\
      %{!p:%{!pg: -lc %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
-     %{pg: -L/usr/lib/pa20_64/libp/ -lgprof -lc\
-       %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}\
-     %{p: -L/usr/lib/pa20_64/libp/ -lprof -lc\
+     %{p:%{!pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
+	   -lprof %{static:-a archive} -lc\
+	   %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
+     %{pg:%{static:%{!mhp-ld:-a shared}%{mhp-ld:-a archive_shared}}\
+       -lgprof %{static:-a archive} -lc\
        %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
    /usr/lib/pa20_64/milli.a"
+#else
+#define LIB_SPEC \
+  "%{!shared:\
+     %{!p:%{!pg: -lc %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
+     %{p:%{!pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\
+	   -lprof %{static:-a archive} -lc\
+	   %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
+     %{pg:%{static:%{mgnu-ld:-a shared}%{!mgnu-ld:-a archive_shared}}\
+       -lgprof %{static:-a archive} -lc\
+       %{static:%{!nolibdld:-a shared -ldld -a archive -lc}}}}\
+   /usr/lib/pa20_64/milli.a"
+#endif
 
 /* Under hpux11, the normal location of the `ld' and `as' programs is the
Index: trunk/src/gcc/gcc/config/pa/pa64-regs.h
===================================================================
--- trunk/src/gcc/gcc/config/pa/pa64-regs.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/pa/pa64-regs.h	(revision 1469)
@@ -170,11 +170,9 @@
    Registers 0  - 31 remain unchanged.
 
-   Registers 32 - 60 are mapped to 72, 74, 76 ...
-
-   Register 88 is mapped to 32.  */
-
+   Registers 32 - 59 are mapped to 72, 74, 76 ...
+
+   Register 60 is mapped to 32.  */
 #define DBX_REGISTER_NUMBER(REGNO) \
-  ((REGNO) <= 31 ? (REGNO) :						\
-   ((REGNO) > 31 && (REGNO) <= 60 ? (REGNO - 32) * 2 + 72 : 32))
+  ((REGNO) <= 31 ? (REGNO) : ((REGNO) < 60 ? (REGNO - 32) * 2 + 72 : 32))
 
 /* We must not use the DBX register numbers for the DWARF 2 CFA column
@@ -293,5 +291,5 @@
 
 #define ADDITIONAL_REGISTER_NAMES \
- {{"%cr11",88}}
+ {{"%cr11",60}}
 
 #define FP_SAVED_REG_LAST 49
Index: trunk/src/gcc/gcc/config/rs6000/rs6000.md
===================================================================
--- trunk/src/gcc/gcc/config/rs6000/rs6000.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/rs6000/rs6000.md	(revision 1469)
@@ -6359,5 +6359,5 @@
 	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 		     (match_operand:SI 2 "const_int_operand" "M,i")))]
-  "TARGET_32BIT && !TARGET_POWER"
+  "TARGET_32BIT && !TARGET_POWER && WORDS_BIG_ENDIAN"
   "@
    {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
@@ -7574,5 +7574,5 @@
 	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
 		     (match_operand:SI 2 "reg_or_cint_operand" "")))]
-  ""
+  "WORDS_BIG_ENDIAN"
   "
 {
@@ -7584,5 +7584,6 @@
       DONE;
     }
-  else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
+  else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT
+	   && WORDS_BIG_ENDIAN)
     {
       emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
Index: trunk/src/gcc/gcc/config/rs6000/sysv4.h
===================================================================
--- trunk/src/gcc/gcc/config/rs6000/sysv4.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/rs6000/sysv4.h	(revision 1469)
@@ -1139,5 +1139,5 @@
 #else
 #define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \
-%{!mnewlib: %{shared:-lc} %{!shared: %{pthread:-lpthread } \
+%{!mnewlib: %{pthread:-lpthread} %{shared:-lc} %{!shared: \
 %{profile:-lc_p} %{!profile:-lc}}}"
 #endif
Index: trunk/src/gcc/gcc/config/rtems.h
===================================================================
--- trunk/src/gcc/gcc/config/rtems.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/rtems.h	(revision 1469)
@@ -1,6 +1,6 @@
 /* Configuration common to all targets running RTEMS. 
-   Copyright (C) 2000, 2002 Free Software Foundation, Inc. 
+   Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc. 
 
-This file is part of GNU CC.
+This file is part of GCC.
 
 GNU CC is free software; you can redistribute it and/or modify
@@ -36,2 +36,16 @@
 #undef ENDFILE_SPEC
 #define ENDFILE_SPEC   ""
+
+/*
+ * Some targets do not set up LIB_SPECS, override it, here.
+ */
+#define STD_LIB_SPEC \
+  "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{!qrtems: " STD_LIB_SPEC "} " \
+"%{!nostdlib: %{qrtems: --start-group \
+ %{!qrtems_debug: -lrtemsbsp -lrtemscpu} \
+ %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
+ -lc -lgcc --end-group %{!qnolinkcmds: -T linkcmds%s}}}"
+
Index: trunk/src/gcc/gcc/config/s390/s390.c
===================================================================
--- trunk/src/gcc/gcc/config/s390/s390.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/s390/s390.c	(revision 1469)
@@ -2270,9 +2270,8 @@
 
 	  else if (GET_CODE (op0) == UNSPEC
-	           && GET_CODE (op1) == CONST_INT)
+	           && GET_CODE (op1) == CONST_INT
+	           && XINT (op0, 1) == 100)
             {
 	      if (XVECLEN (op0, 0) != 1)
-                abort ();
-              if (XINT (op0, 1) != 100)
                 abort ();
 
@@ -2662,4 +2661,7 @@
       rtx reg1 = gen_reg_rtx (double_mode);
 
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
+
       emit_move_insn (gen_highpart (single_mode, reg0), 
 		      force_operand (XEXP (dst, 0), NULL_RTX));
@@ -2758,4 +2760,7 @@
       rtx reg1 = gen_reg_rtx (double_mode);
 
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
+
       emit_move_insn (gen_highpart (single_mode, reg0), 
 		      force_operand (XEXP (dst, 0), NULL_RTX));
@@ -2861,4 +2866,7 @@
       rtx reg0 = gen_reg_rtx (double_mode);
       rtx reg1 = gen_reg_rtx (double_mode);
+
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
 
       emit_move_insn (gen_highpart (single_mode, reg0), 
Index: trunk/src/gcc/gcc/config/s390/s390.md
===================================================================
--- trunk/src/gcc/gcc/config/s390/s390.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/s390/s390.md	(revision 1469)
@@ -1421,4 +1421,8 @@
 ; load_multiple pattern(s).
 ;
+; ??? Due to reload problems with replacing registers inside match_parallel
+; we currently support load_multiple/store_multiple only after reload.
+;
+
 
 (define_expand "load_multiple"
@@ -1426,5 +1430,5 @@
 			  (match_operand 1 "" ""))
 		     (use (match_operand 2 "" ""))])]
-  ""
+  "reload_completed"
   "
 {
@@ -1486,5 +1490,5 @@
 		   [(set (match_operand:DI 1 "register_operand" "=r")
 			 (match_operand:DI 2 "s_operand" "Q"))])]
-  ""
+  "reload_completed"
   "*
 {
@@ -1505,5 +1509,5 @@
 		   [(set (match_operand:SI 1 "register_operand" "=r")
 			 (match_operand:SI 2 "s_operand" "Q"))])]
-  ""
+  "reload_completed"
   "*
 {
@@ -1528,5 +1532,5 @@
 			  (match_operand 1 "" ""))
 		     (use (match_operand 2 "" ""))])]
-  ""
+  "reload_completed"
   "
 {
@@ -1590,5 +1594,5 @@
 		   [(set (match_operand:DI 1 "s_operand" "=Q")
 			 (match_operand:DI 2 "register_operand" "r"))])]
-  ""
+  "reload_completed"
   "*
 {
@@ -1610,5 +1614,5 @@
 		   [(set (match_operand:SI 1 "s_operand" "=Q")
 			 (match_operand:SI 2 "register_operand" "r"))])]
-  ""
+  "reload_completed"
   "*
 {
Index: trunk/src/gcc/gcc/config/sh/sh-protos.h
===================================================================
--- trunk/src/gcc/gcc/config/sh/sh-protos.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/sh/sh-protos.h	(revision 1469)
@@ -119,5 +119,5 @@
 extern int sh_media_register_for_return PARAMS ((void));
 extern void sh_expand_prologue PARAMS ((void));
-extern void sh_expand_epilogue PARAMS ((void));
+extern void sh_expand_epilogue PARAMS ((bool));
 extern int sh_need_epilogue PARAMS ((void));
 extern int initial_elimination_offset PARAMS ((int, int));
Index: trunk/src/gcc/gcc/config/sh/sh.c
===================================================================
--- trunk/src/gcc/gcc/config/sh/sh.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/sh/sh.c	(revision 1469)
@@ -4286,5 +4286,53 @@
 	     to handle this case, so just abort when we see it.  */
 	  if (temp < 0)
-	    abort ();
+	    {
+	      /* If we reached here, the most likely case is the (sibcall)
+		 epilogue for non SHmedia.  Put a special push/pop sequence
+		 for such case as the last resort.  This looks lengthy but
+		 would not be problem because it seems to be very rare.  */
+	      if (! TARGET_SHMEDIA && (emit_fn != frame_insn))
+		{
+		  rtx adj_reg, tmp_reg, mem;
+
+		  /* ??? There is still the slight possibility that r4 or r5
+		     have been reserved as fixed registers or assigned as
+		     global registers, and they change during an interrupt.
+		     There are possible ways to handle this:
+		     - If we are adjusting the frame pointer (r14), we can do
+		       with a single temp register and an ordinary push / pop
+		       on the stack.
+		     - Grab any call-used or call-saved registers (i.e. not
+		       fixed or globals) for the temps we need.  We might
+		       also grab r14 if we are adjusting the stack pointer.
+		       If we can't find enough available registers, issue
+		       a diagnostic and abort - the user must have reserved
+		       way too many registers.
+		     But since all this is rather unlikely to happen and
+		     would require extra testing, we just abort if r4 / r5
+		     are not available.  */
+		  if (fixed_regs[4] || fixed_regs[5]
+		      || global_regs[4] || global_regs[5])
+		    abort ();
+
+		  adj_reg = gen_rtx_REG (GET_MODE (reg), 4);
+		  tmp_reg = gen_rtx_REG (GET_MODE (reg), 5);
+		  emit_move_insn (gen_rtx_MEM (Pmode, reg), adj_reg);
+		  emit_insn (GEN_MOV (adj_reg, GEN_INT (size)));
+		  emit_insn (GEN_ADD3 (adj_reg, adj_reg, reg));
+		  mem = gen_rtx_MEM (Pmode, gen_rtx_PRE_DEC (Pmode, adj_reg));
+		  emit_move_insn (mem, tmp_reg);
+		  emit_move_insn (tmp_reg, gen_rtx_MEM (Pmode, reg));
+		  mem = gen_rtx_MEM (Pmode, gen_rtx_PRE_DEC (Pmode, adj_reg));
+		  emit_move_insn (mem, tmp_reg);
+		  emit_move_insn (reg, adj_reg);
+		  mem = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, reg));
+		  emit_move_insn (adj_reg, mem);
+		  mem = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, reg));
+		  emit_move_insn (tmp_reg, mem);
+		  return;
+		}
+	      else
+		abort ();
+	    }
 	  const_reg = gen_rtx_REG (GET_MODE (reg), temp);
 
@@ -4852,5 +4900,5 @@
 
 void
-sh_expand_epilogue ()
+sh_expand_epilogue (bool sibcall_p)
 {
   HOST_WIDE_INT live_regs_mask[(FIRST_PSEUDO_REGISTER + 31) / 32];
@@ -4860,6 +4908,19 @@
   int save_flags = target_flags;
   int frame_size;
+  int temp;
 
   calc_live_regs (&d, live_regs_mask);
+
+  if (! sibcall_p)
+    temp = 7;
+  else if (TARGET_SHMEDIA)
+    temp = 1;
+  else
+    {
+      for (i = FIRST_GENERAL_REG; i <= LAST_GENERAL_REG; i++)
+	if (TEST_HARD_REG_BIT (live_regs_mask, i))
+	  break;
+      temp = (i <= LAST_GENERAL_REG) ? i : -1;
+    }
 
   if (TARGET_SH5 && d % (STACK_BOUNDARY / BITS_PER_UNIT))
@@ -4871,5 +4932,5 @@
   if (frame_pointer_needed)
     {
-      output_stack_adjust (frame_size, frame_pointer_rtx, 7, emit_insn);
+      output_stack_adjust (frame_size, frame_pointer_rtx, temp, emit_insn);
 
       /* We must avoid moving the stack pointer adjustment past code
@@ -4887,5 +4948,5 @@
 	 frame.  */
       emit_insn (gen_blockage ());
-      output_stack_adjust (frame_size, stack_pointer_rtx, 7, emit_insn);
+      output_stack_adjust (frame_size, stack_pointer_rtx, temp, emit_insn);
     }
 
@@ -5063,5 +5124,5 @@
 		       + d + d_rounding
 		       + current_function_args_info.stack_regs * 8,
-		       stack_pointer_rtx, 7, emit_insn);
+		       stack_pointer_rtx, (sibcall_p ? -1 : temp), emit_insn);
 
   /* Switch back to the normal stack if necessary.  */
@@ -5087,5 +5148,5 @@
 
       start_sequence ();
-      sh_expand_epilogue ();
+      sh_expand_epilogue (0);
       epilogue = get_insns ();
       end_sequence ();
Index: trunk/src/gcc/gcc/config/sh/sh.md
===================================================================
--- trunk/src/gcc/gcc/config/sh/sh.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/sh/sh.md	(revision 1469)
@@ -6427,5 +6427,5 @@
   "
 {
-  sh_expand_epilogue ();
+  sh_expand_epilogue (1);
   if (TARGET_SHCOMPACT)
     {
@@ -7172,5 +7172,5 @@
   "
 {
-  sh_expand_epilogue ();
+  sh_expand_epilogue (0);
   emit_jump_insn (gen_return ());
   DONE;
Index: trunk/src/gcc/gcc/config/sparc/linux.h
===================================================================
--- trunk/src/gcc/gcc/config/sparc/linux.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/sparc/linux.h	(revision 1469)
@@ -246,4 +246,7 @@
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
 #endif
+
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS       1
 
 #if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
Index: trunk/src/gcc/gcc/config/sparc/linux64.h
===================================================================
--- trunk/src/gcc/gcc/config/sparc/linux64.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/sparc/linux64.h	(revision 1469)
@@ -308,4 +308,7 @@
 
 /* #define DWARF_OFFSET_SIZE PTR_SIZE */
+
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS       1
 
 #if defined(HAVE_LD_EH_FRAME_HDR)
Index: trunk/src/gcc/gcc/config/sparc/sparc.c
===================================================================
--- trunk/src/gcc/gcc/config/sparc/sparc.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/sparc/sparc.c	(revision 1469)
@@ -1362,4 +1362,32 @@
 
   return 0;
+}
+
+/* Return 1 if OP is valid for the lhs of a compare insn.  */
+
+int
+compare_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) == ZERO_EXTRACT)
+    return (register_operand (XEXP (op, 0), mode)
+	    && small_int_or_double (XEXP (op, 1), mode)
+	    && small_int_or_double (XEXP (op, 2), mode)
+	    /* This matches cmp_zero_extract.  */
+	    && ((mode == SImode
+		 && ((GET_CODE (XEXP (op, 2)) == CONST_INT
+		      && INTVAL (XEXP (op, 2)) > 19)
+		     || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE
+			 && CONST_DOUBLE_LOW (XEXP (op, 2)) > 19)))
+		/* This matches cmp_zero_extract_sp64.  */
+		|| (mode == DImode
+		    && TARGET_ARCH64
+		    && ((GET_CODE (XEXP (op, 2)) == CONST_INT
+			 && INTVAL (XEXP (op, 2)) > 51)
+			|| (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE
+			    && CONST_DOUBLE_LOW (XEXP (op, 2)) > 51)))));
+  else
+    return register_operand (op, mode);
 }
 
Index: trunk/src/gcc/gcc/config/sparc/sparc.h
===================================================================
--- trunk/src/gcc/gcc/config/sparc/sparc.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/sparc/sparc.h	(revision 1469)
@@ -1239,4 +1239,18 @@
    {-1, -1, -1, 0x20},	/* GENERAL_OR_EXTRA_FP_REGS */	\
    {-1, -1, -1, 0x3f}}	/* ALL_REGS */
+
+/* Defines invalid mode changes.  Borrowed from pa64-regs.h.
+
+   SImode loads to floating-point registers are not zero-extended.
+   The definition for LOAD_EXTEND_OP specifies that integer loads
+   narrower than BITS_PER_WORD will be zero-extended.  As a result,
+   we inhibit changes from SImode unless they are to a mode that is
+   identical in size.  */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)		\
+  (TARGET_ARCH64						\
+   && (FROM) == SImode						\
+   && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)		\
+   ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
 
 /* The same information, inverted:
@@ -2593,8 +2607,16 @@
 #define LETF2_LIBCALL "_Q_fle"
 
+/* These functions were added in SCD 2.3, so not necessarily all targets
+   support them.  */
+#define FLOATDITF2_LIBCALL "_Q_lltoq"
+#define FIX_TRUNCTFDI2_LIBCALL "_Q_qtoll"
+#define FIXUNS_TRUNCTFDI2_LIBCALL "_Q_qtoull"
+
+#define DITF_CONVERSION_LIBFUNCS	0
+
 /* Assume by default that the _Qp_* 64-bit libcalls are implemented such
    that the inputs are fully consumed before the output memory is clobbered.  */
 
-#define TARGET_BUGGY_QP_LIB	0
+#define TARGET_BUGGY_QP_LIB		0
 
 /* We can define the TFmode sqrt optab only if TARGET_FPU.  This is because
@@ -2630,4 +2652,11 @@
 	fixunstfsi_libfunc						\
 	  = init_one_libfunc (FIXUNS_TRUNCTFSI2_LIBCALL);		\
+	if (DITF_CONVERSION_LIBFUNCS)					\
+	  {								\
+	    floatditf_libfunc = init_one_libfunc (FLOATDITF2_LIBCALL);	\
+	    fixtfdi_libfunc = init_one_libfunc (FIX_TRUNCTFDI2_LIBCALL);\
+	    fixunstfdi_libfunc						\
+	      = init_one_libfunc (FIXUNS_TRUNCTFDI2_LIBCALL);		\
+	  }								\
 	if (TARGET_FPU)							\
 	  sqrt_optab->handlers[(int) TFmode].libfunc			\
@@ -3052,4 +3081,5 @@
 {"clobbered_register", {REG}},						\
 {"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}},		\
+{"compare_operand", {SUBREG, REG, ZERO_EXTRACT}},			\
 {"const64_operand", {CONST_INT, CONST_DOUBLE}},				\
 {"const64_high_operand", {CONST_INT, CONST_DOUBLE}},
Index: trunk/src/gcc/gcc/config/sparc/sparc.md
===================================================================
--- trunk/src/gcc/gcc/config/sparc/sparc.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/sparc/sparc.md	(revision 1469)
@@ -292,8 +292,11 @@
 (define_expand "cmpsi"
   [(set (reg:CC 100)
-	(compare:CC (match_operand:SI 0 "register_operand" "")
+	(compare:CC (match_operand:SI 0 "compare_operand" "")
 		    (match_operand:SI 1 "arith_operand" "")))]
   ""
 {
+  if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
+    operands[0] = force_reg (SImode, operands[0]);
+
   sparc_compare_op0 = operands[0];
   sparc_compare_op1 = operands[1];
@@ -303,8 +306,11 @@
 (define_expand "cmpdi"
   [(set (reg:CCX 100)
-	(compare:CCX (match_operand:DI 0 "register_operand" "")
+	(compare:CCX (match_operand:DI 0 "compare_operand" "")
 		     (match_operand:DI 1 "arith_double_operand" "")))]
   "TARGET_ARCH64"
 {
+  if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
+    operands[0] = force_reg (DImode, operands[0]);
+
   sparc_compare_op0 = operands[0];
   sparc_compare_op1 = operands[1];
Index: trunk/src/gcc/gcc/config/xtensa/xtensa-protos.h
===================================================================
--- trunk/src/gcc/gcc/config/xtensa/xtensa-protos.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/xtensa/xtensa-protos.h	(revision 1469)
@@ -1,4 +1,4 @@
 /* Prototypes of target machine for GNU compiler for Xtensa.
-   Copyright 2001,2002,2003 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
@@ -71,5 +71,5 @@
 extern int xtensa_expand_block_move PARAMS ((rtx *));
 extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode));
-extern bool xtensa_copy_incoming_a7 PARAMS ((rtx *, enum machine_mode));
+extern rtx xtensa_copy_incoming_a7 PARAMS ((rtx));
 extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int));
 extern void xtensa_expand_nonlocal_goto PARAMS ((rtx *));
@@ -78,5 +78,5 @@
 
 #ifdef TREE_CODE
-extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
+extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, int));
 extern void xtensa_va_start PARAMS ((tree, rtx));
 extern rtx xtensa_va_arg PARAMS ((tree, tree));
@@ -94,5 +94,4 @@
 extern enum reg_class xtensa_secondary_reload_class
   PARAMS ((enum reg_class, enum machine_mode, rtx, int));
-extern int a7_overlap_mentioned_p PARAMS ((rtx x));
 #endif /* RTX_CODE */
 
Index: trunk/src/gcc/gcc/config/xtensa/xtensa.c
===================================================================
--- trunk/src/gcc/gcc/config/xtensa/xtensa.c	(revision 1466)
+++ trunk/src/gcc/gcc/config/xtensa/xtensa.c	(revision 1469)
@@ -1,4 +1,4 @@
 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
-   Copyright 2001,2002,2003 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
@@ -91,5 +91,7 @@
 {
   int accesses_prev_frame;
-  bool incoming_a7_copied;
+  bool need_a7_copy;
+  bool vararg_a7;
+  rtx set_frame_ptr_insn;
 };
 
@@ -1279,6 +1281,5 @@
 	operands[1] = force_reg (mode, operands[1]);
 
-      if (xtensa_copy_incoming_a7 (operands, mode))
-	return 1;
+      operands[1] = xtensa_copy_incoming_a7 (operands[1]);
     }
 
@@ -1312,69 +1313,113 @@
 
 
-/* Check if this move is copying an incoming argument in a7.  If so,
-   emit the move, followed by the special "set_frame_ptr"
-   unspec_volatile insn, at the very beginning of the function.  This
-   is necessary because the register allocator will ignore conflicts
-   with a7 and may assign some other pseudo to a7.  If that pseudo was
-   assigned prior to this move, it would clobber the incoming argument
-   in a7.  By copying the argument out of a7 as the very first thing,
-   and then immediately following that with an unspec_volatile to keep
-   the scheduler away, we should avoid any problems.  */
-
-bool
-xtensa_copy_incoming_a7 (operands, mode)
-     rtx *operands;
-     enum machine_mode mode;
-{
-  if (a7_overlap_mentioned_p (operands[1])
-      && !cfun->machine->incoming_a7_copied)
-    {
-      rtx mov;
-      switch (mode)
-	{
-	case DFmode:
-	  mov = gen_movdf_internal (operands[0], operands[1]);
-	  break;
-	case SFmode:
-	  mov = gen_movsf_internal (operands[0], operands[1]);
-	  break;
-	case DImode:
-	  mov = gen_movdi_internal (operands[0], operands[1]);
-	  break;
-	case SImode:
-	  mov = gen_movsi_internal (operands[0], operands[1]);
-	  break;
-	case HImode:
-	  mov = gen_movhi_internal (operands[0], operands[1]);
-	  break;
-	case QImode:
-	  mov = gen_movqi_internal (operands[0], operands[1]);
-	  break;
-	default:
-	  abort ();
-	}
-
-      /* Insert the instructions before any other argument copies.
-	 (The set_frame_ptr insn comes _after_ the move, so push it
-	 out first.)  */
+/* Check if an incoming argument in a7 is expected to be used soon and
+   if OPND is a register or register pair that includes a7.  If so,
+   create a new pseudo and copy a7 into that pseudo at the very
+   beginning of the function, followed by the special "set_frame_ptr"
+   unspec_volatile insn.  The return value is either the original
+   operand, if it is not a7, or the new pseudo containing a copy of
+   the incoming argument.  This is necessary because the register
+   allocator will ignore conflicts with a7 and may either assign some
+   other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
+   the incoming argument in a7.  By copying the argument out of a7 as
+   the very first thing, and then immediately following that with an
+   unspec_volatile to keep the scheduler away, we should avoid any
+   problems.  Putting the set_frame_ptr insn at the beginning, with
+   only the a7 copy before it, also makes it easier for the prologue
+   expander to initialize the frame pointer after the a7 copy and to
+   fix up the a7 copy to use the stack pointer instead of the frame
+   pointer.  */
+
+rtx
+xtensa_copy_incoming_a7 (opnd)
+     rtx opnd;
+{
+  rtx entry_insns = 0;
+  rtx reg, tmp;
+  enum machine_mode mode;
+
+  if (!cfun->machine->need_a7_copy)
+    return opnd;
+
+  /* This function should never be called again once a7 has been copied.  */
+  if (cfun->machine->set_frame_ptr_insn)
+    abort ();
+
+  mode = GET_MODE (opnd);
+
+  /* The operand using a7 may come in a later instruction, so just return
+     the original operand if it doesn't use a7.  */
+  reg = opnd;
+  if (GET_CODE (reg) == SUBREG)
+    {
+      if (SUBREG_BYTE (reg) != 0)
+	abort ();
+      reg = SUBREG_REG (reg);
+    }
+  if (GET_CODE (reg) != REG
+      || REGNO (reg) > A7_REG
+      || REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) <= A7_REG)
+    return opnd;
+
+  /* 1-word args will always be in a7; 2-word args in a6/a7.  */
+  if (REGNO (reg) + HARD_REGNO_NREGS (A7_REG, mode) - 1 != A7_REG)
+    abort ();
+
+  cfun->machine->need_a7_copy = false;
+
+  /* Copy a7 to a new pseudo at the function entry.  Use gen_raw_REG to
+     create the REG for a7 so that hard_frame_pointer_rtx is not used.  */
+
+  push_to_sequence (entry_insns);
+  tmp = gen_reg_rtx (mode);
+
+  switch (mode)
+    {
+    case DFmode:
+    case DImode:
+      emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
+				     gen_rtx_REG (SImode, A7_REG - 1)));
+      emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
+				     gen_raw_REG (SImode, A7_REG)));
+      break;
+    case SFmode:
+      emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
+      break;
+    case SImode:
+      emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
+      break;
+    case HImode:
+      emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
+      break;
+    case QImode:
+      emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
+      break;
+    default:
+      abort ();
+    }
+
+  cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
+  entry_insns = get_insns ();
+  end_sequence ();
+
+  if (cfun->machine->vararg_a7)
+    {
+      /* This is called from within builtin_savereg, so we're already
+	 inside a start_sequence that will be placed at the start of
+	 the function.  */
+      emit_insn (entry_insns);
+    }
+  else
+    {
+      /* Put entry_insns after the NOTE that starts the function.  If
+	 this is inside a start_sequence, make the outer-level insn
+	 chain current, so the code is placed at the start of the
+	 function.  */
       push_topmost_sequence ();
-      emit_insn_after (gen_set_frame_ptr (), get_insns ());
-      emit_insn_after (mov, get_insns ());
+      emit_insn_after (entry_insns, get_insns ());
       pop_topmost_sequence ();
-
-      /* Ideally the incoming argument in a7 would only be copied
-	 once, since propagating a7 into the body of a function
-	 will almost certainly lead to errors.  However, there is
-	 at least one harmless case (in GCSE) where the original
-	 copy from a7 is changed to copy into a new pseudo.  Thus,
-	 we use a flag to only do this special treatment for the
-	 first copy of a7.  */
-
-      cfun->machine->incoming_a7_copied = true;
-
-      return 1;
-    }
-
-  return 0;
+    }
+
+  return tmp;
 }
 
@@ -1724,10 +1769,10 @@
 
 void
-init_cumulative_args (cum, fntype, libname)
+init_cumulative_args (cum, incoming)
      CUMULATIVE_ARGS *cum;	/* argument info to initialize */
-     tree fntype ATTRIBUTE_UNUSED;	/* tree ptr for function decl */
-     rtx libname ATTRIBUTE_UNUSED;	/* SYMBOL_REF of library name or 0 */
+     int incoming;
 {
   cum->arg_words = 0;
+  cum->incoming = incoming;
 }
 
@@ -1770,5 +1815,4 @@
   int *arg_words;
   int regno;
-  enum machine_mode result_mode;
 
   arg_words = &cum->arg_words;
@@ -1787,31 +1831,9 @@
 
   regno = regbase + *arg_words;
-  result_mode = (mode == BLKmode ? TYPE_MODE (type) : mode);
-
-  /* We need to make sure that references to a7 are represented with
-     rtx that is not equal to hard_frame_pointer_rtx.  For BLKmode and
-     modes bigger than 2 words (because we only have patterns for
-     modes of 2 words or smaller), we can't control the expansion
-     unless we explicitly list the individual registers in a PARALLEL. */
-
-  if ((mode == BLKmode || words > 2)
-      && regno < A7_REG
-      && regno + words > A7_REG)
-    {
-      rtx result;
-      int n;
-
-      result = gen_rtx_PARALLEL (result_mode, rtvec_alloc (words));
-      for (n = 0; n < words; n++)
-	{
-	  XVECEXP (result, 0, n) =
-	    gen_rtx_EXPR_LIST (VOIDmode,
-			       gen_raw_REG (SImode, regno + n),
-			       GEN_INT (n * UNITS_PER_WORD));
-	}
-      return result;
-    }
-
-  return gen_raw_REG (result_mode, regno);
+
+  if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
+    cfun->machine->need_a7_copy = true;
+
+  return gen_rtx_REG (mode, regno);
 }
 
@@ -2190,6 +2212,4 @@
     rtx first;
 {
-  rtx insn, set_frame_ptr_insn = 0;
-    
   unsigned long tsize = compute_frame_size (get_frame_size ());
   if (tsize < (1 << (12+3)))
@@ -2207,32 +2227,13 @@
     return;
 
-  /* Search all instructions, looking for the insn that sets up the
-     frame pointer.  This search will fail if the function does not
-     have an incoming argument in $a7, but in that case, we can just
-     set up the frame pointer at the very beginning of the
-     function. */
-
-  for (insn = first; insn; insn = NEXT_INSN (insn))
-    {
-      rtx pat;
-
-      if (!INSN_P (insn))
-	continue;
-
-      pat = PATTERN (insn);
-      if (GET_CODE (pat) == SET
-	  && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
-	  && (XINT (SET_SRC (pat), 1) == UNSPECV_SET_FP))
-	{
-	  set_frame_ptr_insn = insn;
-	  break;
-	}
-    }
-
-  if (set_frame_ptr_insn)
-    {
+  if (cfun->machine->set_frame_ptr_insn)
+    {
+      rtx insn;
+
       /* for all instructions prior to set_frame_ptr_insn, replace
 	 hard_frame_pointer references with stack_pointer */
-      for (insn = first; insn != set_frame_ptr_insn; insn = NEXT_INSN (insn))
+      for (insn = first;
+	   insn != cfun->machine->set_frame_ptr_insn;
+	   insn = NEXT_INSN (insn))
 	{
 	  if (INSN_P (insn))
@@ -2382,7 +2383,6 @@
   int arg_words = current_function_arg_words;
   int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
-  int i;
-
-  if (gp_left == 0)
+
+  if (gp_left <= 0)
     return const0_rtx;
 
@@ -2397,13 +2397,8 @@
 					arg_words * UNITS_PER_WORD));
 
-  /* Note: Don't use move_block_from_reg() here because the incoming
-     argument in a7 cannot be represented by hard_frame_pointer_rtx.
-     Instead, call gen_raw_REG() directly so that we get a distinct
-     instance of (REG:SI 7). */
-  for (i = 0; i < gp_left; i++)
-    {
-      emit_move_insn (operand_subword (dest, i, 1, BLKmode),
-		      gen_raw_REG (SImode, GP_ARG_FIRST + arg_words + i));
-    }
+  cfun->machine->need_a7_copy = true;
+  cfun->machine->vararg_a7 = true;
+  move_block_from_reg (GP_ARG_FIRST + arg_words, dest, gp_left,
+		       gp_left * UNITS_PER_WORD);
 
   return XEXP (gp_regs, 0);
@@ -2725,54 +2720,4 @@
 
 
-/* A customized version of reg_overlap_mentioned_p that only looks for
-   references to a7 (as opposed to hard_frame_pointer_rtx). */
-
-int
-a7_overlap_mentioned_p (x)
-     rtx x;
-{
-  int i, j;
-  unsigned int x_regno;
-  const char *fmt;
-
-  if (GET_CODE (x) == REG)
-    {
-      x_regno = REGNO (x);
-      return (x != hard_frame_pointer_rtx
-	      && x_regno < A7_REG + 1
-	      && x_regno + HARD_REGNO_NREGS (A7_REG, GET_MODE (x)) > A7_REG);
-    }
-
-  if (GET_CODE (x) == SUBREG
-      && GET_CODE (SUBREG_REG (x)) == REG
-      && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
-    {
-      x_regno = subreg_regno (x);
-      return (SUBREG_REG (x) != hard_frame_pointer_rtx
-	      && x_regno < A7_REG + 1
-	      && x_regno + HARD_REGNO_NREGS (A7_REG, GET_MODE (x)) > A7_REG);
-    }
-
-  /* X does not match, so try its subexpressions.  */
-  fmt = GET_RTX_FORMAT (GET_CODE (x));
-  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-	{
-	  if (a7_overlap_mentioned_p (XEXP (x, i)))
-	    return 1;
-	}
-      else if (fmt[i] == 'E')
-	{
-	  for (j = XVECLEN (x, i) - 1; j >=0; j--)
-	    if (a7_overlap_mentioned_p (XVECEXP (x, i, j)))
-	      return 1;
-	}
-    }
-
-  return 0;
-}
-
-
 /* Some Xtensa targets support multiple bss sections.  If the section
    name ends with ".bss", add SECTION_BSS to the flags.  */
Index: trunk/src/gcc/gcc/config/xtensa/xtensa.h
===================================================================
--- trunk/src/gcc/gcc/config/xtensa/xtensa.h	(revision 1466)
+++ trunk/src/gcc/gcc/config/xtensa/xtensa.h	(revision 1469)
@@ -1,4 +1,4 @@
 /* Definitions of Tensilica's Xtensa target machine for GNU compiler.
-   Copyright 2001,2002,2003 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
@@ -855,21 +855,19 @@
   ((N) >= GP_OUTGOING_ARG_FIRST && (N) <= GP_OUTGOING_ARG_LAST)
 
-/* Define a data type for recording info about an argument list
-   during the scan of that argument list.  This data type should
-   hold all necessary information about the function itself
-   and about the args processed so far, enough to enable macros
-   such as FUNCTION_ARG to determine where the next arg should go. */
-typedef struct xtensa_args {
-    int arg_words;		/* # total words the arguments take */
+/* Record the number of argument words seen so far, along with a flag to
+   indicate whether these are incoming arguments.  (FUNCTION_INCOMING_ARG
+   is used for both incoming and outgoing args, so a separate flag is
+   needed.  */
+typedef struct xtensa_args
+{
+  int arg_words;
+  int incoming;
 } CUMULATIVE_ARGS;
 
-/* Initialize a variable CUM of type CUMULATIVE_ARGS
-   for a call to a function whose data type is FNTYPE.
-   For a library call, FNTYPE is 0. */
 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT)		\
-  init_cumulative_args (&CUM, FNTYPE, LIBNAME)
+  init_cumulative_args (&CUM, 0)
 
 #define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME)		\
-  init_cumulative_args (&CUM, FNTYPE, LIBNAME)
+  init_cumulative_args (&CUM, 1)
 
 /* Update the data in CUM to advance over an argument
Index: trunk/src/gcc/gcc/config/xtensa/xtensa.md
===================================================================
--- trunk/src/gcc/gcc/config/xtensa/xtensa.md	(revision 1466)
+++ trunk/src/gcc/gcc/config/xtensa/xtensa.md	(revision 1469)
@@ -1,4 +1,4 @@
 ;; GCC machine description for Tensilica's Xtensa architecture.
-;; Copyright (C) 2001 Free Software Foundation, Inc.
+;; Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 ;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
@@ -943,6 +943,5 @@
 	operands[1] = force_reg (DImode, operands[1]);
 
-      if (xtensa_copy_incoming_a7 (operands, DImode))
-	DONE;
+      operands[1] = xtensa_copy_incoming_a7 (operands[1]);
     }
 }")
@@ -1117,6 +1116,5 @@
 	operands[1] = force_reg (SFmode, operands[1]);
 
-      if (xtensa_copy_incoming_a7 (operands, SFmode))
-	DONE;
+      operands[1] = xtensa_copy_incoming_a7 (operands[1]);
     }
 }")
@@ -1199,6 +1197,5 @@
 	operands[1] = force_reg (DFmode, operands[1]);
 
-      if (xtensa_copy_incoming_a7 (operands, DFmode))
-	DONE;
+      operands[1] = xtensa_copy_incoming_a7 (operands[1]);
     }
 }")
@@ -1303,5 +1300,14 @@
 ;;
 
-(define_insn "ashlsi3"
+(define_expand "ashlsi3"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(ashift:SI (match_operand:SI 1 "register_operand" "")
+		   (match_operand:SI 2 "arith_operand" "")))]
+  ""
+{
+  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
+})
+
+(define_insn "ashlsi3_internal"
   [(set (match_operand:SI 0 "register_operand" "=a,a")
 	(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
Index: trunk/src/gcc/gcc/cp/ChangeLog
===================================================================
--- trunk/src/gcc/gcc/cp/ChangeLog	(revision 1466)
+++ trunk/src/gcc/gcc/cp/ChangeLog	(revision 1469)
@@ -1,2 +1,175 @@
+2004-05-31  Release Manager
+
+	* GCC 3.3.4 Released.
+
+2004-05-16  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport from mainline:
+	2004-03-18  Mark Mitchell  <mark@codesourcery.com>
+	* call.c (build_conditional_expr): Do not call force_rvalue for
+	operands of void_type when the conditional expression itself has
+	void type.
+
+2004-05-08  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+	* Make-lang.in (cp/init.o): Depend on diagnostic.h.
+	* except.c (do_free_exception): Prototype.
+	* init.c: Include "diagnostic.h".
+
+2004-05-04  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+
+	Backport:
+	2004-04-01  Mark Mitchell  <mark@codesourcery.com>
+	PR c++/14810
+	* decl.c (maybe_push_cleanup_level): Robustify.
+
+2004-05-01  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport from gcc-3_4-branch
+	2004-03-30  Mark Mitchell  <mark@codesourcery.com>
+	            Jakub Jelinek  <jakub@redhat.com>
+	PR c++/14763
+	* pt.c (tsubst_default_argument): Clear current_function_decl.
+	* decl2.c (mark_used): Don't segfault if cfun != NULL but
+	current_function_decl == NULL.
+
+2004-05-01  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport from gcc-3_4-branch:
+	2004-03-30  Mark Mitchell  <mark@codesourcery.com>
+	PR c++/14724
+	* decl.c (start_decl_1): Do not decide whether or not to create a
+	new cleanup level until after the type has been completed.
+
+2004-04-01  Richard Henderson  <rth@redhat.com>
+
+        PR c++/14804
+        * decl.c (cp_finish_decl): Preserve TREE_READONLY more often.
+        * typeck2.c (split_nonconstant_init): Clear TREE_READONLY.
+
+2003-03-17  Matt Austern  <austern@apple.com>
+
+	Backport:
+	PR debug/14079
+	* decl.c (add_decl_to_level): Add extern variables, as well
+	as static, to static_decls array.
+	
+2004-03-12  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport:
+	2004-03-11  Mark Mitchell  <mark@codesourcery.com>
+	PR c++/14476
+	* decl.c (xref_tag): Do not create dummy ENUMERAL_TYPEs.
+
+2004-03-12  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport:
+	2004-03-08  Mark Mitchell  <mark@codesourcery.com>
+	PR c++/14401
+	* class.c (check_field_decls): Complain about non-static data
+	members of reference type in unions.  Propagate
+	CLASSTYPE_REF_FIELDS_NEED_INIT and
+	CLASSTYPE_READONLY_FIELDS_NEED_INIT from the types of non-static
+	data members.
+	* init.c (perform_member_init): Complain about members with const
+	type that are not explicitly initialized.
+
+2004-03-12  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport:
+	2004-03-09  Mark Mitchell  <mark@codesourcery.com>
+        PR c++/14230
+        * call.c (initialize_reference): Handle initializers that are
+        class-member access expressions applies to rvalues.
+
+2004-03-12  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport:
+	2004-01-12  Richard Henderson  <rth@redhat.com>
+	PR opt/10776
+	* typeck2.c (split_nonconstant_init_1, split_nonconstant_init): New.
+	(store_init_value): Use it.
+	* decl.c (check_initializer): Expect full initialization code
+	from store_init_value.
+	* init.c (expand_aggr_init_1): Likewise.
+	* decl2.c (maybe_emit_vtables): Abort if runtime init needed.
+
+2004-03-09  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+	PR c++/14409
+	* pt.c (determine_specialization): For member templates, match also
+	constness.
+
+2004-03-05  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport:
+	2004-02-04  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/9941
+	* rtti.c (tinfo_base_init): Use import_export_tinfo to decide the
+	linkage for the typeinfo name string.
+
+2004-02-24  Jason Merrill  <jason@redhat.com>
+
+	PR c++/13944
+	* except.c (do_free_exception): Remove #if 0 wrapper.
+	(build_throw): Use it if we elide a copy into the exception object.
+
+2004-03-01  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	* decl.c (current_binding_level): Define as an lvalue.
+
+2004-02-23  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+	PR c++/13635
+	* pt.c (push_template_decl_real): Make sure DECL_TI_ARGS of DECL
+	has full set of arguments.
+
+2004-02-23  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+	PR c++/14250
+	* cvt.c (build_expr_type_conversion): Type must be complete before
+	looking up for conversions.
+
+2004-02-22  Jakub Jelinek  <jakub@redhat.com>
+
+	* decl.c (reshape_init): Convert array designator to sizetype.
+
+2004-02-22  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport from mainline
+        2004-02-13  Mark Mitchell  <mark@codesourcery.com>
+	PR c++/14083
+	* call.c (build_conditional_expr): Call force_rvalue on the
+	non-void operand in the case that one result is a throw-expression
+	and the other is not.
+
+2004-02-22  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport from mainline
+	2003-02-06  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+	PR c++/14033
+	* decl.c (require_complete_types_for_parms): Do not insert
+	error_mark_node in the parameter list.
+
+2004-02-22  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport from mainline
+	2004-02-04  Mark Mitchell  <mark@codesourcery.com>
+	PR c++/13932
+	* call.c (convert_like_real): Use "converting" rather than
+	"argument" as the descriptive keyword to
+	dubious_conversion_warnings.
+	* typeck.c (convert_for_assignment): Do not call
+	dubious_conversion_warnings.
+
+2004-02-22  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+	Backport from mainline
+	2004-02-02  Mark Mitchell  <mark@codesourcery.com>
+	PR c++/13907
+	* call.c (convert_class_to_reference): Keep better track of
+	pedantically invalid user-defined conversions.
+
 2004-02-14  Release Manager
 
Index: trunk/src/gcc/gcc/cp/call.c
===================================================================
--- trunk/src/gcc/gcc/cp/call.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/call.c	(revision 1469)
@@ -1092,13 +1092,17 @@
 	  
 	  if (cand)
-	    /* Build a standard conversion sequence indicating the
-	       binding from the reference type returned by the
-	       function to the desired REFERENCE_TYPE.  */
-	    cand->second_conv
-	      = (direct_reference_binding 
-		 (reference_type, 
-		  build1 (IDENTITY_CONV, 
-			  TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
-			  NULL_TREE)));
+            {
+              /* Build a standard conversion sequence indicating the
+                 binding from the reference type returned by the
+                 function to the desired REFERENCE_TYPE.  */
+              cand->second_conv
+                = (direct_reference_binding 
+                   (reference_type, 
+                    build1 (IDENTITY_CONV, 
+                            TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
+                            NULL_TREE)));
+              ICS_BAD_FLAG (cand->second_conv)
+                |= ICS_BAD_FLAG (TREE_VEC_ELT (cand->convs, 0));
+            }
 	}
       conversions = TREE_CHAIN (conversions);
@@ -3239,9 +3243,25 @@
 
 	 --Both the second and the third operands have type void; the
-	   result is of type void and is an rvalue.  */
-      if ((TREE_CODE (arg2) == THROW_EXPR)
-	  ^ (TREE_CODE (arg3) == THROW_EXPR))
-	result_type = ((TREE_CODE (arg2) == THROW_EXPR) 
-		       ? arg3_type : arg2_type);
+	   result is of type void and is an rvalue.  
+
+         We must avoid calling force_rvalue for expressions of type
+	 "void" because it will complain that their value is being
+	 used.   */
+      if (TREE_CODE (arg2) == THROW_EXPR 
+	  && TREE_CODE (arg3) != THROW_EXPR)
+	{
+	  if (!VOID_TYPE_P (arg3_type))
+	    arg3 = force_rvalue (arg3);
+	  arg3_type = TREE_TYPE (arg3);
+	  result_type = arg3_type;
+	}
+      else if (TREE_CODE (arg2) != THROW_EXPR 
+	       && TREE_CODE (arg3) == THROW_EXPR)
+	{
+	  if (!VOID_TYPE_P (arg2_type))
+	    arg2 = force_rvalue (arg2);
+	  arg2_type = TREE_TYPE (arg2);
+	  result_type = arg2_type;
+	}
       else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
 	result_type = void_type_node;
@@ -4094,5 +4114,5 @@
   if (issue_conversion_warnings)
     expr = dubious_conversion_warnings
-             (totype, expr, "argument", fn, argnum);
+             (totype, expr, "converting", fn, argnum);
   switch (TREE_CODE (convs))
     {
@@ -6191,4 +6211,14 @@
 	  var = make_temporary_var_for_ref_to_temp (decl, type);
 	  layout_decl (var, 0);
+	  /* If the rvalue is the result of a function call it will be
+	     a TARGET_EXPR.  If it is some other construct (such as a
+	     member access expression where the underlying object is
+	     itself the result of a function call), turn it into a
+	     TARGET_EXPR here.  It is important that EXPR be a
+	     TARGET_EXPR below since otherwise the INIT_EXPR will
+	     attempt to make a bitwise copy of EXPR to intialize
+	     VAR. */
+	  if (TREE_CODE (expr) != TARGET_EXPR)
+	    expr = get_target_expr (expr);
 	  /* Create the INIT_EXPR that will initialize the temporary
 	     variable.  */
Index: trunk/src/gcc/gcc/cp/class.c
===================================================================
--- trunk/src/gcc/gcc/cp/class.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/class.c	(revision 1469)
@@ -3236,6 +3236,27 @@
       /* If we've gotten this far, it's a data member, possibly static,
 	 or an enumerator.  */
-
       DECL_CONTEXT (x) = t;
+
+      /* When this goes into scope, it will be a non-local reference.  */
+      DECL_NONLOCAL (x) = 1;
+
+      if (TREE_CODE (t) == UNION_TYPE)
+	{
+	  /* [class.union]
+
+	     If a union contains a static data member, or a member of
+	     reference type, the program is ill-formed. */
+	  if (TREE_CODE (x) == VAR_DECL)
+	    {
+	      cp_error_at ("`%D' may not be static because it is a member of a union", x);
+	      continue;
+	    }
+	  if (TREE_CODE (type) == REFERENCE_TYPE)
+	    {
+	      cp_error_at ("`%D' may not have reference type `%T' because it is a member of a union",
+			   x, type);
+	      continue;
+	    }
+	}
 
       /* ``A local class cannot have static data members.'' ARM 9.4 */
@@ -3268,18 +3289,6 @@
 	continue;
 	  
-      /* When this goes into scope, it will be a non-local reference.  */
-      DECL_NONLOCAL (x) = 1;
-
-      if (TREE_CODE (x) == CONST_DECL)
+      if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
 	continue;
-
-      if (TREE_CODE (x) == VAR_DECL)
-	{
-	  if (TREE_CODE (t) == UNION_TYPE)
-	    /* Unions cannot have static members.  */
-	    cp_error_at ("field `%D' declared static in union", x);
-	      
-	  continue;
-	}
 
       /* Now it can only be a FIELD_DECL.  */
@@ -3312,4 +3321,12 @@
       if (TREE_CODE (type) == POINTER_TYPE)
 	has_pointers = 1;
+
+      if (CLASS_TYPE_P (type))
+        {
+          if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
+            SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
+          if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
+            SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
+        }
 
       if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
Index: trunk/src/gcc/gcc/cp/cvt.c
===================================================================
--- trunk/src/gcc/gcc/cp/cvt.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/cvt.c	(revision 1469)
@@ -1076,6 +1076,7 @@
   /* The code for conversions from class type is currently only used for
      delete expressions.  Other expressions are handled by build_new_op.  */
-
-  if (! TYPE_HAS_CONVERSION (basetype))
+  if (!complete_type_or_else (basetype, expr))
+    return error_mark_node;
+  if (!TYPE_HAS_CONVERSION (basetype))
     return NULL_TREE;
 
Index: trunk/src/gcc/gcc/cp/decl2.c
===================================================================
--- trunk/src/gcc/gcc/cp/decl2.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/decl2.c	(revision 1469)
@@ -1858,5 +1858,9 @@
       mark_vtable_entries (vtbl);
       if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
-	store_init_value (vtbl, DECL_INITIAL (vtbl));
+	{
+	  /* It had better be all done at compile-time.  */
+	  if (store_init_value (vtbl, DECL_INITIAL (vtbl)))
+	    abort ();
+	}
 
       if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
@@ -4882,4 +4886,5 @@
 	       || TREE_NOTHROW (decl)
 	       || !cfun
+               || !current_function_decl
 	       /* If we already know the current function can't throw,
 		  then we don't need to work hard to prove it.  */
Index: trunk/src/gcc/gcc/cp/init.c
===================================================================
--- trunk/src/gcc/gcc/cp/init.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/init.c	(revision 1469)
@@ -33,4 +33,5 @@
 #include "except.h"
 #include "toplev.h"
+#include "diagnostic.h"
 #include "ggc.h"
 
@@ -391,4 +392,7 @@
 	  else if (TREE_CODE (type) == REFERENCE_TYPE)
 	    pedwarn ("uninitialized reference member `%D'", member);
+          else if (CP_TYPE_CONST_P (type))
+            pedwarn ("uninitialized member '%D' with 'const' type '%T'",
+                     member, type);
 	}
       else if (TREE_CODE (init) == TREE_LIST)
@@ -1287,6 +1291,7 @@
 	 record in the DECL_INITIAL for EXP.  That means there's
 	 nothing more we have to do.  */
-      if (store_init_value (exp, init))
-	finish_expr_stmt (build (INIT_EXPR, type, exp, init));
+      init = store_init_value (exp, init);
+      if (init)
+	finish_expr_stmt (init);
       return;
     }
Index: trunk/src/gcc/gcc/cp/pt.c
===================================================================
--- trunk/src/gcc/gcc/cp/pt.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/pt.c	(revision 1469)
@@ -961,5 +961,5 @@
        instantiation unless and until it is actually needed.  */
     return spec;
-    
+
   /* There should be as many levels of arguments as there are
      levels of parameters.  */
@@ -1156,4 +1156,5 @@
 	{
 	  tree decl_arg_types;
+	  tree fn_arg_types;
 
 	  /* DECL might be a specialization of FN.  */
@@ -1172,6 +1173,14 @@
 	     by get_bindings below.  */
 
-	  if (list_length (TYPE_ARG_TYPES (TREE_TYPE (fn)))
-	      != list_length (decl_arg_types))
+	  fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
+	  if (list_length (fn_arg_types) != list_length (decl_arg_types))
+	    continue;
+
+	  /* For a non-static member function, we need to make sure that
+	     the const qualification is the same. This can be done by
+	     checking the 'this' in the argument list.  */
+	  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+	      && !same_type_p (TREE_VALUE (fn_arg_types), 
+			       TREE_VALUE (decl_arg_types)))
 	    continue;
 
@@ -2919,4 +2928,11 @@
     }
 
+  /* The DECL_TI_ARGS of DECL contains full set of arguments refering
+     back to its most general template.  If TMPL is a specialization,
+     ARGS may only have the innermost set of arguments.  Add the missing
+     argument levels if necessary.  */
+  if (DECL_TEMPLATE_INFO (tmpl))
+    args = add_outermost_template_args (DECL_TI_ARGS (tmpl), args);
+
   info = tree_cons (tmpl, args, NULL_TREE);
 
@@ -5891,4 +5907,8 @@
   /* FN is already the desired FUNCTION_DECL.  */
   push_access_scope (fn);
+  /* The default argument expression should not be considered to be
+     within the scope of FN.  Since push_access_scope sets
+     current_function_decl, we must explicitly clear it here.  */
+  current_function_decl = NULL_TREE;
 
   arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
Index: trunk/src/gcc/gcc/cp/rtti.c
===================================================================
--- trunk/src/gcc/gcc/cp/rtti.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/rtti.c	(revision 1469)
@@ -765,5 +765,5 @@
     DECL_EXTERNAL (name_decl) = 0;
     TREE_PUBLIC (name_decl) = 1;
-    comdat_linkage (name_decl);
+    import_export_tinfo (name_decl, target, typeinfo_in_lib_p (target));
     /* External name of the string containing the type's name has a
        special name.  */
Index: trunk/src/gcc/gcc/cp/typeck.c
===================================================================
--- trunk/src/gcc/gcc/cp/typeck.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/typeck.c	(revision 1469)
@@ -5953,6 +5953,4 @@
     return error_mark_node;
 
-  rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
-
   /* The RHS of an assignment cannot have void type.  */
   if (coder == VOID_TYPE)
Index: trunk/src/gcc/gcc/cp/typeck2.c
===================================================================
--- trunk/src/gcc/gcc/cp/typeck2.c	(revision 1466)
+++ trunk/src/gcc/gcc/cp/typeck2.c	(revision 1469)
@@ -298,4 +298,107 @@
 
 
+/* The recursive part of split_nonconstant_init.  DEST is an lvalue
+   expression to which INIT should be assigned.  INIT is a CONSTRUCTOR.
+   PCODE is a pointer to the tail of a chain of statements being emitted.
+   The return value is the new tail of that chain after new statements
+   are generated.  */
+
+static tree *
+split_nonconstant_init_1 (tree dest, tree init, tree *pcode)
+{
+  tree *pelt, elt, type = TREE_TYPE (dest);
+  tree sub, code, inner_type = NULL;
+  bool array_type_p = false;
+
+  pelt = &CONSTRUCTOR_ELTS (init);
+  switch (TREE_CODE (type))
+    {
+    case ARRAY_TYPE:
+      inner_type = TREE_TYPE (type);
+      array_type_p = true;
+      /* FALLTHRU */
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+      while ((elt = *pelt))
+	{
+	  tree field_index = TREE_PURPOSE (elt);
+	  tree value = TREE_VALUE (elt);
+
+	  if (!array_type_p)
+	    inner_type = TREE_TYPE (field_index);
+
+	  if (TREE_CODE (value) == CONSTRUCTOR)
+	    {
+	      if (array_type_p)
+	        sub = build (ARRAY_REF, inner_type, dest, field_index);
+	      else
+	        sub = build (COMPONENT_REF, inner_type, dest, field_index);
+
+	      pcode = split_nonconstant_init_1 (sub, value, pcode);
+	    }
+	  else if (!initializer_constant_valid_p (value, inner_type))
+	    {
+	      *pelt = TREE_CHAIN (elt);
+
+	      if (array_type_p)
+	        sub = build (ARRAY_REF, inner_type, dest, field_index);
+	      else
+	        sub = build (COMPONENT_REF, inner_type, dest, field_index);
+
+	      code = build (MODIFY_EXPR, inner_type, sub, value);
+	      code = build_stmt (EXPR_STMT, code);
+
+	      *pcode = code;
+	      pcode = &TREE_CHAIN (code);
+	      continue;
+	    }
+	  pelt = &TREE_CHAIN (elt);
+	}
+      break;
+
+    case VECTOR_TYPE:
+      if (!initializer_constant_valid_p (init, type))
+	{
+	  CONSTRUCTOR_ELTS (init) = NULL;
+	  code = build (MODIFY_EXPR, type, dest, init);
+	  code = build_stmt (EXPR_STMT, code);
+	  pcode = &TREE_CHAIN (code);
+	}
+      break;
+
+    default:
+      abort ();
+    }
+
+  return pcode;
+}
+
+/* A subroutine of store_init_value.  Splits non-constant static 
+   initializer INIT into a constant part and generates code to
+   perform the non-constant part of the initialization to DEST.
+   Returns the code for the runtime init.  */
+
+static tree
+split_nonconstant_init (tree dest, tree init)
+{
+  tree code;
+
+  if (TREE_CODE (init) == CONSTRUCTOR)
+    {
+      code = build_stmt (COMPOUND_STMT, NULL_TREE);
+      split_nonconstant_init_1 (dest, init, &COMPOUND_BODY (code));
+      code = build1 (STMT_EXPR, void_type_node, code);
+      TREE_SIDE_EFFECTS (code) = 1;
+      DECL_INITIAL (dest) = init;
+      TREE_READONLY (dest) = 0;
+    }
+  else
+    code = build (INIT_EXPR, TREE_TYPE (dest), dest, init);
+
+  return code;
+}
+
 /* Perform appropriate conversions on the initial value of a variable,
    store it in the declaration DECL,
@@ -313,7 +416,6 @@
    Perhaps a warning should be generated?
 
-   Returns value of initializer if initialization could not be
-   performed for static variable.  In that case, caller must do
-   the storing.  */
+   Returns code to be executed if initialization could not be performed
+   for static variable.  In that case, caller must emit the code.  */
 
 tree
@@ -387,9 +489,9 @@
      build_aggr_init without checking DECL_INITIAL.  So just return.  */
   else if (TYPE_NEEDS_CONSTRUCTING (type))
-    return value;
+    return build (INIT_EXPR, type, decl, value);
   else if (TREE_STATIC (decl)
 	   && (! TREE_CONSTANT (value)
 	       || ! initializer_constant_valid_p (value, TREE_TYPE (value))))
-    return value;
+    return split_nonconstant_init (decl, value);
   
   /* Store the VALUE in DECL_INITIAL.  If we're building a
Index: trunk/src/gcc/gcc/doc/extend.texi
===================================================================
--- trunk/src/gcc/gcc/doc/extend.texi	(revision 1466)
+++ trunk/src/gcc/gcc/doc/extend.texi	(revision 1469)
@@ -1038,7 +1038,5 @@
 their addresses or store values into them.
 
-Standard C++ allows compound expressions and conditional expressions as
-lvalues, and permits casts to reference type, so use of this extension
-is deprecated for C++ code.
+All these extensions are deprecated.
 
 For example, a compound expression can be assigned, provided the last
Index: trunk/src/gcc/gcc/doc/gccint.texi
===================================================================
--- trunk/src/gcc/gcc/doc/gccint.texi	(revision 1466)
+++ trunk/src/gcc/gcc/doc/gccint.texi	(revision 1469)
@@ -49,5 +49,5 @@
 @copying
 Copyright @copyright{} 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
Index: trunk/src/gcc/gcc/doc/include/gcc-common.texi
===================================================================
--- trunk/src/gcc/gcc/doc/include/gcc-common.texi	(revision 1466)
+++ trunk/src/gcc/gcc/doc/include/gcc-common.texi	(revision 1469)
@@ -5,5 +5,5 @@
 @c Common values used in the GCC manuals:
 
-@set version-GCC 3.3.3
+@set version-GCC 3.3.4
 
 @c DEVELOPMENT is set to indicate an in-development version,
Index: trunk/src/gcc/gcc/doc/install.texi
===================================================================
--- trunk/src/gcc/gcc/doc/install.texi	(revision 1466)
+++ trunk/src/gcc/gcc/doc/install.texi	(revision 1469)
@@ -3151,4 +3151,11 @@
 64-bit target libraries.
 
+GCC 3.3 triggers code generation bugs in earlier versions of the GNU
+compiler (especially GCC 3.0.x versions), which lead to the miscompilation
+of the stage1 compiler and the subsequent failure of the bootstrap process.
+A workaround is to use GCC 3.2.3 as an intermediary stage, i.e. to bootstrap
+that compiler with the base compiler and then use it to bootstrap the final
+compiler.
+
 @html
 <hr />
Index: trunk/src/gcc/gcc/doc/tm.texi
===================================================================
--- trunk/src/gcc/gcc/doc/tm.texi	(revision 1466)
+++ trunk/src/gcc/gcc/doc/tm.texi	(revision 1469)
@@ -1,3 +1,3 @@
-@c Copyright (C) 1988,1989,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003
+@c Copyright (C) 1988,1989,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
 @c Free Software Foundation, Inc.
 @c This is part of the GCC manual.
@@ -5204,4 +5204,32 @@
 @end table
 
+@deftypefn {Target Hook} bool TARGET_FIXED_CONDITION_CODE_REGS (unsigned int *, unsigned int *)
+On targets which do not use @code{(cc0)}, and which use a hard
+register rather than a pseudo-register to hold condition codes, the
+regular CSE passes are often not able to identify cases in which the
+hard register is set to a common value.  Use this hook to enable a
+small pass which optimizes such cases.  This hook should return true
+to enable this pass, and it should set the integers to which its
+arguments point to the hard register numbers used for condition codes.
+When there is only one such register, as is true on most systems, the
+integer pointed to by the second argument should be set to
+@code{INVALID_REGNUM}.
+
+The default version of this hook returns false.
+@end deftypefn
+
+@deftypefn {Target Hook} enum machine_mode TARGET_CC_MODES_COMPATIBLE (enum machine_mode, enum machine_mode)
+On targets which use multiple condition code modes in class
+@code{MODE_CC}, it is sometimes the case that a comparison can be
+validly done in more than one mode.  On such a system, define this
+target hook to take two mode arguments and to return a mode in which
+both comparisons may be validly done.  If there is no such mode,
+return @code{VOIDmode}.
+
+The default version of this hook checks whether the modes are the
+same.  If they are, it returns that mode.  If they are different, it
+returns @code{VOIDmode}.
+@end deftypefn
+
 @node Costs
 @section Describing Relative Costs of Operations
Index: trunk/src/gcc/gcc/f/BUGS
===================================================================
--- trunk/src/gcc/gcc/f/BUGS	(revision 1466)
+++ trunk/src/gcc/gcc/f/BUGS	(revision 1469)
@@ -3,5 +3,5 @@
 it is normally included within source distributions.
 
-   This file lists known bugs in the GCC-3.3.3 version of the GNU
+   This file lists known bugs in the GCC-3.3.4 version of the GNU
 Fortran compiler.  Copyright (C)
 1995,1996,1997,1998,1999,2000,2001,2002 Free Software Foundation, Inc.
@@ -13,5 +13,5 @@
 
    This section identifies bugs that `g77' _users_ might run into in
-the GCC-3.3.3 version of `g77'.  This includes bugs that are actually
+the GCC-3.3.4 version of `g77'.  This includes bugs that are actually
 in the `gcc' back end (GBE) or in `libf2c', because those sets of code
 are at least somewhat under the control of (and necessarily intertwined
Index: trunk/src/gcc/gcc/f/ChangeLog
===================================================================
--- trunk/src/gcc/gcc/f/ChangeLog	(revision 1466)
+++ trunk/src/gcc/gcc/f/ChangeLog	(revision 1469)
@@ -1,2 +1,36 @@
+2004-05-31  Release Manager
+
+	* GCC 3.3.4 Released.
+
+Sat May  8 17:50:43 2004  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+	Backport:
+	
+	2004-02-24  Michael Matz  <matz@suse.de>
+	
+	* sta.c (ffesta_save_): Don't break aliasing rules.
+
+2004-04-18  Gerald Pfeifer  <gerald@pfeifer.com>
+
+	* g77.texi (Floating-point Errors): Avoid referencing 
+	http://www.linuxsupportline.com/~billm/ which as has been hijacked.
+
+2004-03-21  Gerald Pfeifer  <gerald@pfeifer.com>
+
+	* g77.texi (Aligned Data): Remove obsolete paragraph including a
+	broken link.
+	(Floating-point Errors): Remove links to http://www.validgh.com/
+	which was "hijacked".
+	(Language): Fix link to Fortran books.
+	(Projects): Remove obsolete paragraph including a broken link to
+	ftp://alpha.gnu.org/gnu/g77/projects/.
+	(Trouble): Remove obsolete paragraph including a broken link to
+	ftp://alpha.gnu.org/g77.plan.
+	
+	* invoke.texi (Overall Options): Remove broken reference to
+	rat7.uue (which was of dubious copyright status anyways).
+
+	* root.texi (www-burley): Fix URL.
+	
 2004-02-14  Release Manager
 
Index: trunk/src/gcc/gcc/f/NEWS
===================================================================
--- trunk/src/gcc/gcc/f/NEWS	(revision 1466)
+++ trunk/src/gcc/gcc/f/NEWS	(revision 1469)
@@ -3,5 +3,5 @@
 it is normally included within source distributions.
 
-   This file lists news about the GCC-3.3.3 version (and some other
+   This file lists news about the GCC-3.3.4 version (and some other
 versions) of the GNU Fortran compiler.  Copyright (C)
 1995,1996,1997,1998,1999,2000,2001,2002,2003 Free Software Foundation,
Index: trunk/src/gcc/gcc/f/g77.texi
===================================================================
--- trunk/src/gcc/gcc/f/g77.texi	(revision 1466)
+++ trunk/src/gcc/gcc/f/g77.texi	(revision 1469)
@@ -4,5 +4,5 @@
 
 @set last-update 2003-05-13
-@set copyrights-g77 1995,1996,1997,1998,1999,2000,2001,2002,2003
+@set copyrights-g77 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
 
 @include root.texi
@@ -850,5 +850,5 @@
 (If you need a text on Fortran,
 a few freely available electronic references have pointers from
-@uref{http://www.fortran.com/fortran/Books/}.  There is a `cooperative
+@uref{http://www.fortran.com/F/books.html}.  There is a `cooperative
 net project', @cite{User Notes on Fortran Programming} at
 @uref{ftp://vms.huji.ac.il/fortran/} and mirrors elsewhere; some of this
@@ -8001,11 +8001,4 @@
 (such as GNU/Linux).
 
-@cindex alignment testing
-@cindex testing alignment
-A package that tests the degree to which a Fortran compiler
-(such as @command{g77})
-aligns 64-bit floating-point variables and arrays
-is available at @uref{ftp://alpha.gnu.org/gnu/g77/align/}.
-
 @node Prefer Automatic Uninitialized Variables
 @subsection Prefer Automatic Uninitialized Variables
@@ -8088,8 +8081,4 @@
 missing features that are too much work to add, and some are places
 where people's opinions differ as to what is best.
-
-To find out about major bugs discovered in the current release and
-possible workarounds for them, see
-@uref{ftp://alpha.gnu.org/g77.plan}.
 
 (Note that some of this portion of the manual is lifted
@@ -8628,7 +8617,5 @@
 5-48.
 An online version is available at
-@uref{http://docs.sun.com/},
-and there is a supplemented version, in PostScript form, at
-@uref{http://www.validgh.com/goldberg/paper.ps}.
+@uref{http://docs.sun.com/}.
 
 Information related to the IEEE 754
@@ -8637,13 +8624,8 @@
 see also slides from the short course referenced from
 @uref{http://http.cs.berkeley.edu/%7Efateman/}.
-@uref{http://www.linuxsupportline.com/%7Ebillm/} has a brief
-guide to IEEE 754, a somewhat x86-GNU/Linux-specific FAQ,
-and library code for GNU/Linux x86 systems.
 
 The supplement to the PostScript-formatted Goldberg document,
 referenced above, is available in HTML format.
-See `Differences Among IEEE 754 Implementations' by Doug Priest,
-available online at
-@uref{http://www.validgh.com/goldberg/addendum.html}.
+See `Differences Among IEEE 754 Implementations' by Doug Priest.
 This document explores some of the issues surrounding computing
 of extended (80-bit) results on processors such as the x86,
@@ -10778,6 +10760,4 @@
 design, specification, documentation, coding, or testing,
 the following information should give you some ideas.
-More relevant information might be available from
-@uref{ftp://alpha.gnu.org/gnu/g77/projects/}.
 
 @menu
Index: trunk/src/gcc/gcc/f/invoke.texi
===================================================================
--- trunk/src/gcc/gcc/f/invoke.texi	(revision 1466)
+++ trunk/src/gcc/gcc/f/invoke.texi	(revision 1469)
@@ -1,3 +1,3 @@
-@c Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+@c Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
 @c Free Software Foundation, Inc.
 @c This is part of the G77 manual.   
@@ -6,5 +6,5 @@
 @ignore
 @c man begin COPYRIGHT
-Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
 Free Software Foundation, Inc.
 
@@ -301,7 +301,5 @@
 command, which is available separately (as it is not yet part of the GNU
 Fortran distribution).
-One version in Fortran, adapted for use with @command{g77} is at
-@uref{ftp://members.aol.com/n8tm/rat7.uue} (of uncertain copyright
-status).  Another, public domain version in C is at
+A public domain version in C is at
 @uref{http://sepwww.stanford.edu/sep/prof/ratfor.shar.2}.
 @end table
Index: trunk/src/gcc/gcc/f/root.texi
===================================================================
--- trunk/src/gcc/gcc/f/root.texi	(revision 1466)
+++ trunk/src/gcc/gcc/f/root.texi	(revision 1469)
@@ -12,3 +12,3 @@
 
 @set email-burley craig@@jcb-sc.com
-@set www-burley http://world.std.com/%7Eburley
+@set www-burley http://world.std.com/%7Eburley/
Index: trunk/src/gcc/gcc/f/sta.c
===================================================================
--- trunk/src/gcc/gcc/f/sta.c	(revision 1466)
+++ trunk/src/gcc/gcc/f/sta.c	(revision 1469)
@@ -339,5 +339,5 @@
 				   not tried yet. */
       if (ffesta_current_possible_
-	  == (ffestaPossible_) &ffesta_possible_nonexecs_)
+	  == (ffestaPossible_) &ffesta_possible_nonexecs_.first)
 	{
 	  ffesta_current_possible_ = ffesta_possible_execs_.first;
@@ -383,5 +383,5 @@
 		  if (possible->handler == NULL)
 		    {
-		      if (possible == (ffestaPossible_) &ffesta_possible_nonexecs_)
+		      if (possible == (ffestaPossible_) &ffesta_possible_nonexecs_.first)
 			{
 			  possible = first_exec = ffesta_possible_execs_.first;
Index: trunk/src/gcc/gcc/fixinc/fixincl.x
===================================================================
--- trunk/src/gcc/gcc/fixinc/fixincl.x	(revision 1466)
+++ trunk/src/gcc/gcc/fixinc/fixincl.x	(revision 1469)
@@ -6,5 +6,5 @@
  * directory that GNU C will search.
  *
- * This file contains 163 fixup descriptions.
+ * This file contains 164 fixup descriptions.
  *
  * See README for more information.
@@ -3809,4 +3809,39 @@
 /* * * * * * * * * * * * * * * * * * * * * * * * * *
  *
+ *  Description of Obstack_Lvalue_Cast fix
+ */
+tSCC zObstack_Lvalue_CastName[] =
+     "obstack_lvalue_cast";
+
+/*
+ *  File name selection pattern
+ */
+tSCC zObstack_Lvalue_CastList[] =
+  "|obstack.h|";
+/*
+ *  Machine/OS name selection pattern
+ */
+#define apzObstack_Lvalue_CastMachs (const char**)NULL
+
+/*
+ *  content selection pattern - do fix if pattern found
+ */
+tSCC zObstack_Lvalue_CastSelect0[] =
+       "\\*\\(\\(([^()]*)\\*\\)(.*)\\)\\+\\+ = \\(([^()]*)\\)";
+
+#define    OBSTACK_LVALUE_CAST_TEST_CT  1
+static tTestDesc aObstack_Lvalue_CastTests[] = {
+  { TT_EGREP,    zObstack_Lvalue_CastSelect0, (regex_t*)NULL }, };
+
+/*
+ *  Fix Command Arguments for Obstack_Lvalue_Cast
+ */
+static const char* apzObstack_Lvalue_CastPatch[] = {
+    "format",
+    "((*((%1*)%2) = (%3)), (%2 += sizeof (%1)))",
+    (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
  *  Description of Osf_Namespace_A fix
  */
@@ -6419,7 +6454,7 @@
  *  List of all fixes
  */
-#define REGEX_COUNT          177
+#define REGEX_COUNT          178
 #define MACH_LIST_SIZE_LIMIT 334
-#define FIX_COUNT            163
+#define FIX_COUNT            164
 
 /*
@@ -6522,4 +6557,5 @@
     NEXT_WAIT_UNION_FIXIDX,
     NODEENT_SYNTAX_FIXIDX,
+    OBSTACK_LVALUE_CAST_FIXIDX,
     OSF_NAMESPACE_A_FIXIDX,
     OSF_NAMESPACE_C_FIXIDX,
@@ -7068,4 +7104,9 @@
      aNodeent_SyntaxTests,   apzNodeent_SyntaxPatch, 0 },
 
+  {  zObstack_Lvalue_CastName,    zObstack_Lvalue_CastList,
+     apzObstack_Lvalue_CastMachs,
+     OBSTACK_LVALUE_CAST_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+     aObstack_Lvalue_CastTests,   apzObstack_Lvalue_CastPatch, 0 },
+
   {  zOsf_Namespace_AName,    zOsf_Namespace_AList,
      apzOsf_Namespace_AMachs,
Index: trunk/src/gcc/gcc/fixinc/inclhack.def
===================================================================
--- trunk/src/gcc/gcc/fixinc/inclhack.def	(revision 1466)
+++ trunk/src/gcc/gcc/fixinc/inclhack.def	(revision 1469)
@@ -2133,4 +2133,29 @@
 
 /*
+ *  obstack.h used casts as lvalues.
+ *
+ *  We need to change postincrements of casted pointers (which are
+ *  then dereferenced and assigned into) of the form
+ *
+ *    *((TYPE*)PTRVAR)++ = (VALUE)
+ *
+ *  into expressions like
+ *
+ *    ((*((TYPE*)PTRVAR) = (VALUE)), (PTRVAR += sizeof (TYPE)))
+ *
+ *  which is correct for the cases used in obstack.h since PTRVAR is
+ *  of type char * and the value of the expression is not used.
+ */
+fix = {
+    hackname  = obstack_lvalue_cast;
+    files     = obstack.h;
+    select    = '\*\(\(([^()]*)\*\)(.*)\)\+\+ = \(([^()]*)\)';
+    c_fix     = format;
+    c_fix_arg = "((*((%1*)%2) = (%3)), (%2 += sizeof (%1)))";
+    test_text = "*((void **) (h)->next_free)++ = (aptr)";
+};
+
+
+/*
  *  sys/lc_core.h on some versions of OSF1/4.x pollutes the namespace by
  *  defining regex.h related types.  This causes libg++ build and usage
Index: trunk/src/gcc/gcc/intl/ChangeLog
===================================================================
--- trunk/src/gcc/gcc/intl/ChangeLog	(revision 1466)
+++ trunk/src/gcc/gcc/intl/ChangeLog	(revision 1469)
@@ -1,2 +1,6 @@
+2004-05-31  Release Manager
+
+	* GCC 3.3.4 Released.
+
 2004-02-14  Release Manager
 
Index: trunk/src/gcc/gcc/java/ChangeLog
===================================================================
--- trunk/src/gcc/gcc/java/ChangeLog	(revision 1466)
+++ trunk/src/gcc/gcc/java/ChangeLog	(revision 1469)
@@ -1,2 +1,12 @@
+2004-05-31  Release Manager
+
+	* GCC 3.3.4 Released.
+
+2004-02-26  Andrew Haley  <aph@redhat.com>
+
+	PR java/12890:
+	* parse.y (do_resolve_class): Check return value from
+	breakdown_qualified().
+
 2004-02-14  Release Manager
 
Index: trunk/src/gcc/gcc/java/parse.y
===================================================================
--- trunk/src/gcc/gcc/java/parse.y	(revision 1466)
+++ trunk/src/gcc/gcc/java/parse.y	(revision 1469)
@@ -5800,12 +5800,14 @@
 	 as a class then we fall through.  */
       tree q, left, left_type, right;
-      breakdown_qualified (&left, &right, TYPE_NAME (class_type));
-      BUILD_PTR_FROM_NAME (left_type, left);
-      q = do_resolve_class (enclosing, left_type, decl, cl);
-      if (q)
-	{
-	  enclosing = q;
-	  saved_enclosing_type = TREE_TYPE (q);
-	  BUILD_PTR_FROM_NAME (class_type, right);
+      if (breakdown_qualified (&left, &right, TYPE_NAME (class_type)) == 0)
+	{
+	  BUILD_PTR_FROM_NAME (left_type, left);
+	  q = do_resolve_class (enclosing, left_type, decl, cl);
+	  if (q)
+	    {
+	      enclosing = q;
+	      saved_enclosing_type = TREE_TYPE (q);
+	      BUILD_PTR_FROM_NAME (class_type, right);
+	    }
 	}
     }
Index: trunk/src/gcc/gcc/po/ChangeLog
===================================================================
--- trunk/src/gcc/gcc/po/ChangeLog	(revision 1466)
+++ trunk/src/gcc/gcc/po/ChangeLog	(revision 1469)
@@ -1,2 +1,6 @@
+2004-05-31  Release Manager
+
+	* GCC 3.3.4 Released.
+
 2004-02-14  Release Manager
 
