rpms/gcc/devel gcc44-atom-mnative.patch, NONE, 1.1 gcc44-atom-movbe.patch, NONE, 1.1 gcc44-builtin-object-size.patch, NONE, 1.1 gcc44-epilogue-unwind.patch, NONE, 1.1 gcc44-ix86-insn-length.patch, NONE, 1.1 gcc44-unwind-debug-hook.patch, NONE, 1.1 .cvsignore, 1.269, 1.270 gcc.spec, 1.42, 1.43 sources, 1.272, 1.273 gcc44-pr39856.patch, 1.1, NONE gcc44-pr39942.patch, 1.1, NONE

Jakub Jelinek jakub at fedoraproject.org
Tue Jun 9 14:26:59 UTC 2009


Author: jakub

Update of /cvs/pkgs/rpms/gcc/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12560

Modified Files:
	.cvsignore gcc.spec sources 
Added Files:
	gcc44-atom-mnative.patch gcc44-atom-movbe.patch 
	gcc44-builtin-object-size.patch gcc44-epilogue-unwind.patch 
	gcc44-ix86-insn-length.patch gcc44-unwind-debug-hook.patch 
Removed Files:
	gcc44-pr39856.patch gcc44-pr39942.patch 
Log Message:
4.4.0-7

gcc44-atom-mnative.patch:

--- NEW FILE gcc44-atom-mnative.patch ---
2009-05-20  H.J. Lu  <hongjiu.lu at intel.com>

	* config/i386/driver-i386.c (host_detect_local_cpu): Check
	extended family and model for Intel processors.  Support Intel
	Atom.

--- gcc/config/i386/driver-i386.c	(revision 147735)
+++ gcc/config/i386/driver-i386.c	(revision 147736)
@@ -395,9 +395,22 @@ const char *host_detect_local_cpu (int a
 
   __cpuid (1, eax, ebx, ecx, edx);
 
-  /* We don't care for extended family.  */
   model = (eax >> 4) & 0x0f;
   family = (eax >> 8) & 0x0f;
+  if (vendor == SIG_INTEL)
+    {
+      unsigned int extended_model, extended_family;
+
+      extended_model = (eax >> 12) & 0xf0;
+      extended_family = (eax >> 20) & 0xff;
+      if (family == 0x0f)
+	{
+	  family += extended_family;
+	  model += extended_model;
+	}
+      else if (family == 0x06)
+	model += extended_model;
+    }
 
   has_sse3 = ecx & bit_SSE3;
   has_ssse3 = ecx & bit_SSSE3;
@@ -496,8 +509,8 @@ const char *host_detect_local_cpu (int a
       break;
     case PROCESSOR_PENTIUMPRO:
       if (has_longmode)
-	/* It is Core 2 Duo.  */
-	cpu = "core2";
+	/* It is Core 2 or Atom.  */
+	cpu = (model == 28) ? "atom" : "core2";
       else if (arch)
 	{
 	  if (has_sse3)

gcc44-atom-movbe.patch:

--- NEW FILE gcc44-atom-movbe.patch ---
2009-05-21  H.J. Lu  <hongjiu.lu at intel.com>
	    Uros Bizjak  <ubizjak at gmail.com>

	* config/i386/cpuid.h (bit_MOVBE): New.

	* config/i386/driver-i386.c (host_detect_local_cpu): Check movbe.

	* config/i386/i386.c (OPTION_MASK_ISA_MOVBE_SET): New.
	(OPTION_MASK_ISA_MOVBE_UNSET): Likewise.
	(ix86_handle_option): Handle OPT_mmovbe.
	(ix86_target_string): Add -mmovbe.
	(pta_flags): Add PTA_MOVBE.
	(processor_alias_table): Add PTA_MOVBE to "atom".
	(override_options): Handle PTA_MOVBE.

	* config/i386/i386.h (TARGET_MOVBE): New.

	* config/i386/i386.md (bswapsi2): Check TARGET_MOVBE.
	(*bswapsi_movbe): New.
	(*bswapdi_movbe): Likewise.
	(bswapdi2): Renamed to ...
	(*bswapdi_1): This.
	(bswapdi2): New expander.

	* config/i386/i386.opt (mmovbe): New.

	* doc/invoke.texi: Document -mmovbe.

	* gcc.target/i386/movbe-1.c: New.
	* gcc.target/i386/movbe-2.c: Likewise.

--- gcc/doc/invoke.texi	(revision 147772)
+++ gcc/doc/invoke.texi	(revision 147773)
@@ -577,7 +577,7 @@ Objective-C and Objective-C++ Dialects}.
 -mno-wide-multiply  -mrtd  -malign-double @gol
 -mpreferred-stack-boundary=@var{num}
 -mincoming-stack-boundary=@var{num}
--mcld -mcx16 -msahf -mrecip @gol
+-mcld -mcx16 -msahf -mmovbe -mrecip @gol
 -mmmx  -msse  -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol
 -maes -mpclmul @gol
 -msse4a -m3dnow -mpopcnt -mabm -msse5 @gol
@@ -11458,6 +11458,11 @@ SAHF are load and store instructions, re
 In 64-bit mode, SAHF instruction is used to optimize @code{fmod}, @code{drem}
 or @code{remainder} built-in functions: see @ref{Other Builtins} for details.
 
+ at item -mmovbe
+ at opindex mmovbe
+This option will enable GCC to use movbe instruction to implement
+ at code{__builtin_bswap32} and @code{__builtin_bswap64}.
+
 @item -mrecip
 @opindex mrecip
 This option will enable GCC to use RCPSS and RSQRTSS instructions (and their
--- gcc/testsuite/gcc.target/i386/movbe-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/movbe-1.c	(revision 147773)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmovbe" } */
+
+extern int x;
+
+void
+foo (int i)
+{
+  x = __builtin_bswap32 (i);
+}
+
+int
+bar ()
+{
+  return __builtin_bswap32 (x);
+}
+
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 } } */
--- gcc/testsuite/gcc.target/i386/movbe-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/movbe-2.c	(revision 147773)
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmovbe" } */
+
+extern long long x;
+
+void
+foo (long long i)
+{
+  x = __builtin_bswap64 (i);
+}
+
+long long
+bar ()
+{
+  return __builtin_bswap64 (x);
+}
+
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 4 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 { target lp64 } } } */
--- gcc/config/i386/i386.h	(revision 147772)
+++ gcc/config/i386/i386.h	(revision 147773)
@@ -59,6 +59,7 @@ see the files COPYING3 and COPYING.RUNTI
 #define TARGET_ABM	OPTION_ISA_ABM
 #define TARGET_POPCNT	OPTION_ISA_POPCNT
 #define TARGET_SAHF	OPTION_ISA_SAHF
+#define TARGET_MOVBE	OPTION_ISA_MOVBE
 #define TARGET_AES	OPTION_ISA_AES
 #define TARGET_PCLMUL	OPTION_ISA_PCLMUL
 #define TARGET_CMPXCHG16B OPTION_ISA_CX16
--- gcc/config/i386/i386.md	(revision 147772)
+++ gcc/config/i386/i386.md	(revision 147773)
@@ -16105,7 +16105,7 @@ (define_expand "bswapsi2"
 	(bswap:SI (match_operand:SI 1 "register_operand" "")))]
   ""
 {
-  if (!TARGET_BSWAP)
+  if (!(TARGET_BSWAP || TARGET_MOVBE))
     {
       rtx x = operands[0];
 
@@ -16117,6 +16117,21 @@ (define_expand "bswapsi2"
     }
 })
 
+(define_insn "*bswapsi_movbe"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
+	(bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
+  "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "@
+    bswap\t%0
+    movbe\t{%1, %0|%0, %1}
+    movbe\t{%1, %0|%0, %1}"
+  [(set_attr "type" "*,imov,imov")
+   (set_attr "modrm" "*,1,1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_extra" "*,1,1")
+   (set_attr "length" "2,*,*")
+   (set_attr "mode" "SI")])
+
 (define_insn "*bswapsi_1"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(bswap:SI (match_operand:SI 1 "register_operand" "0")))]
@@ -16145,7 +16160,29 @@ (define_insn "bswaphi_lowpart"
   [(set_attr "length" "4")
    (set_attr "mode" "HI")])
 
-(define_insn "bswapdi2"
+(define_expand "bswapdi2"
+  [(set (match_operand:DI 0 "register_operand" "")
+	(bswap:DI (match_operand:DI 1 "register_operand" "")))]
+  "TARGET_64BIT"
+  "")
+
+(define_insn "*bswapdi_movbe"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
+	(bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
+  "TARGET_64BIT && TARGET_MOVBE
+   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "@
+    bswap\t%0
+    movbe\t{%1, %0|%0, %1}
+    movbe\t{%1, %0|%0, %1}"
+  [(set_attr "type" "*,imov,imov")
+   (set_attr "modrm" "*,1,1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_extra" "*,1,1")
+   (set_attr "length" "3,*,*")
+   (set_attr "mode" "DI")])
+
+(define_insn "*bswapdi_1"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(bswap:DI (match_operand:DI 1 "register_operand" "0")))]
   "TARGET_64BIT"
--- gcc/config/i386/cpuid.h	(revision 147772)
+++ gcc/config/i386/cpuid.h	(revision 147773)
@@ -29,6 +29,7 @@
 #define bit_CMPXCHG16B	(1 << 13)
 #define bit_SSE4_1	(1 << 19)
 #define bit_SSE4_2	(1 << 20)
+#define bit_MOVBE	(1 << 22)
 #define bit_POPCNT	(1 << 23)
 #define bit_AES		(1 << 25)
 #define bit_XSAVE	(1 << 26)
--- gcc/config/i386/i386.opt	(revision 147772)
+++ gcc/config/i386/i386.opt	(revision 147773)
@@ -339,6 +339,10 @@ msahf
 Target Report Mask(ISA_SAHF) Var(ix86_isa_flags) VarExists Save
 Support code generation of sahf instruction in 64bit x86-64 code.
 
+mmovbe
+Target Report Mask(ISA_MOVBE) Var(ix86_isa_flags) VarExists Save
+Support code generation of movbe instruction.
+
 maes
 Target Report Mask(ISA_AES) Var(ix86_isa_flags) VarExists Save
 Support AES built-in functions and code generation
--- gcc/config/i386/driver-i386.c	(revision 147772)
+++ gcc/config/i386/driver-i386.c	(revision 147773)
@@ -378,7 +378,7 @@ const char *host_detect_local_cpu (int a
   /* Extended features */
   unsigned int has_lahf_lm = 0, has_sse4a = 0;
   unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0;
-  unsigned int has_sse4_1 = 0, has_sse4_2 = 0;
+  unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0;
   unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0;
   unsigned int has_pclmul = 0;
 
@@ -408,6 +408,7 @@ const char *host_detect_local_cpu (int a
   has_sse4_2 = ecx & bit_SSE4_2;
   has_avx = ecx & bit_AVX;
   has_cmpxchg16b = ecx & bit_CMPXCHG16B;
+  has_movbe = ecx & bit_MOVBE;
   has_popcnt = ecx & bit_POPCNT;
   has_aes = ecx & bit_AES;
   has_pclmul = ecx & bit_PCLMUL;
@@ -597,6 +598,8 @@ const char *host_detect_local_cpu (int a
 	options = concat (options, "-mcx16 ", NULL);
       if (has_lahf_lm)
 	options = concat (options, "-msahf ", NULL);
+      if (has_movbe)
+	options = concat (options, "-mmovbe ", NULL);
       if (has_aes)
 	options = concat (options, "-maes ", NULL);
       if (has_pclmul)
--- gcc/config/i386/i386.c	(revision 147772)
+++ gcc/config/i386/i386.c	(revision 147773)
@@ -1965,9 +1965,11 @@ static int ix86_isa_flags_explicit;
 
 #define OPTION_MASK_ISA_ABM_SET \
   (OPTION_MASK_ISA_ABM | OPTION_MASK_ISA_POPCNT)
+
 #define OPTION_MASK_ISA_POPCNT_SET OPTION_MASK_ISA_POPCNT
 #define OPTION_MASK_ISA_CX16_SET OPTION_MASK_ISA_CX16
 #define OPTION_MASK_ISA_SAHF_SET OPTION_MASK_ISA_SAHF
+#define OPTION_MASK_ISA_MOVBE_SET OPTION_MASK_ISA_MOVBE
 
 /* Define a set of ISAs which aren't available when a given ISA is
    disabled.  MMX and SSE ISAs are handled separately.  */
@@ -2009,6 +2011,7 @@ static int ix86_isa_flags_explicit;
 #define OPTION_MASK_ISA_POPCNT_UNSET OPTION_MASK_ISA_POPCNT
 #define OPTION_MASK_ISA_CX16_UNSET OPTION_MASK_ISA_CX16
 #define OPTION_MASK_ISA_SAHF_UNSET OPTION_MASK_ISA_SAHF
+#define OPTION_MASK_ISA_MOVBE_UNSET OPTION_MASK_ISA_MOVBE
 
 /* Vectorization library interface and handlers.  */
 tree (*ix86_veclib_handler)(enum built_in_function, tree, tree) = NULL;
@@ -2299,6 +2302,19 @@ ix86_handle_option (size_t code, const c
 	}
       return true;
 
+    case OPT_mmovbe:
+      if (value)
+	{
+	  ix86_isa_flags |= OPTION_MASK_ISA_MOVBE_SET;
+	  ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_SET;
+	}
+      else
+	{
+	  ix86_isa_flags &= ~OPTION_MASK_ISA_MOVBE_UNSET;
+	  ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_UNSET;
+	}
+      return true;
+
     case OPT_maes:
       if (value)
 	{
@@ -2361,6 +2377,7 @@ ix86_target_string (int isa, int flags, 
     { "-mmmx",		OPTION_MASK_ISA_MMX },
     { "-mabm",		OPTION_MASK_ISA_ABM },
     { "-mpopcnt",	OPTION_MASK_ISA_POPCNT },
+    { "-mmovbe",	OPTION_MASK_ISA_MOVBE },
     { "-maes",		OPTION_MASK_ISA_AES },
     { "-mpclmul",	OPTION_MASK_ISA_PCLMUL },
   };
@@ -2577,7 +2594,8 @@ override_options (bool main_args_p)
       PTA_AES = 1 << 17,
       PTA_PCLMUL = 1 << 18,
       PTA_AVX = 1 << 19,
-      PTA_FMA = 1 << 20 
+      PTA_FMA = 1 << 20,
+      PTA_MOVBE = 1 << 21
     };
 
   static struct pta
@@ -2621,7 +2639,7 @@ override_options (bool main_args_p)
 	| PTA_SSSE3 | PTA_CX16},
       {"atom", PROCESSOR_ATOM, CPU_ATOM,
 	PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
-	| PTA_SSSE3 | PTA_CX16},
+	| PTA_SSSE3 | PTA_CX16 | PTA_MOVBE},
       {"geode", PROCESSOR_GEODE, CPU_GEODE,
 	PTA_MMX | PTA_3DNOW | PTA_3DNOW_A |PTA_PREFETCH_SSE},
       {"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
@@ -2935,6 +2953,9 @@ override_options (bool main_args_p)
 	if (!(TARGET_64BIT && (processor_alias_table[i].flags & PTA_NO_SAHF))
 	    && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SAHF))
 	  ix86_isa_flags |= OPTION_MASK_ISA_SAHF;
+	if (processor_alias_table[i].flags & PTA_MOVBE
+	    && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_MOVBE))
+	  ix86_isa_flags |= OPTION_MASK_ISA_MOVBE;
 	if (processor_alias_table[i].flags & PTA_AES
 	    && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AES))
 	  ix86_isa_flags |= OPTION_MASK_ISA_AES;

gcc44-builtin-object-size.patch:

--- NEW FILE gcc44-builtin-object-size.patch ---
2009-06-08  Jakub Jelinek  <jakub at redhat.com>

	* tree-object-size.c (addr_object_size): Add OSI argument.
	Handle also INDIRECT_REF with SSA_NAME inside of it as base address.
	(compute_builtin_object_size, expr_object_size): Adjust callers.
	(plus_stmt_object_size): Call addr_object_size instead of
	compute_builtin_object_size.

	* gcc.dg/builtin-object-size-2.c (test1): Adjust expected results.
	* gcc.dg/builtin-object-size-4.c (test1): Adjust expected results.
	* gcc.dg/builtin-object-size-6.c: New test.

--- gcc/testsuite/gcc.dg/builtin-object-size-4.c	(revision 148278)
+++ gcc/testsuite/gcc.dg/builtin-object-size-4.c	(revision 148279)
@@ -130,15 +130,15 @@ test1 (void *q, int x)
     abort ();    
   if (__builtin_object_size (&vara[5], 3) != 0)
     abort ();
-  if (__builtin_object_size (&vara[0].a, 3) != 0)
+  if (__builtin_object_size (&vara[0].a, 3) != sizeof (vara[0].a))
     abort ();
-  if (__builtin_object_size (&vara[10].a[0], 3) != 0)
+  if (__builtin_object_size (&vara[10].a[0], 3) != sizeof (vara[0].a))
     abort ();
-  if (__builtin_object_size (&vara[5].a[4], 3) != 0)
+  if (__builtin_object_size (&vara[5].a[4], 3) != sizeof (vara[0].a) - 4)
     abort ();
-  if (__builtin_object_size (&vara[5].b, 3) != 0)
+  if (__builtin_object_size (&vara[5].b, 3) != sizeof (vara[0].b))
     abort ();
-  if (__builtin_object_size (&vara[7].c[7], 3) != 0)
+  if (__builtin_object_size (&vara[7].c[7], 3) != sizeof (vara[0].c) - 7)
     abort ();
   if (__builtin_object_size (zerol, 3) != 0)
     abort ();
--- gcc/testsuite/gcc.dg/builtin-object-size-2.c	(revision 148278)
+++ gcc/testsuite/gcc.dg/builtin-object-size-2.c	(revision 148279)
@@ -130,15 +130,15 @@ test1 (void *q, int x)
     abort ();    
   if (__builtin_object_size (&vara[5], 1) != (size_t) -1)
     abort ();
-  if (__builtin_object_size (&vara[0].a, 1) != (size_t) -1)
+  if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a))
     abort ();
-  if (__builtin_object_size (&vara[10].a[0], 1) != (size_t) -1)
+  if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a))
     abort ();
-  if (__builtin_object_size (&vara[5].a[4], 1) != (size_t) -1)
+  if (__builtin_object_size (&vara[5].a[4], 1) != sizeof (vara[0].a) - 4)
     abort ();
-  if (__builtin_object_size (&vara[5].b, 1) != (size_t) -1)
+  if (__builtin_object_size (&vara[5].b, 1) != sizeof (vara[0].b))
     abort ();
-  if (__builtin_object_size (&vara[7].c[7], 1) != (size_t) -1)
+  if (__builtin_object_size (&vara[7].c[7], 1) != sizeof (vara[0].c) - 7)
     abort ();
   if (__builtin_object_size (zerol, 1) != 0)
     abort ();
--- gcc/testsuite/gcc.dg/builtin-object-size-6.c	(revision 0)
+++ gcc/testsuite/gcc.dg/builtin-object-size-6.c	(revision 148279)
@@ -0,0 +1,435 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+extern void exit (int);
+extern void *malloc (size_t);
+extern void free (void *);
+
+struct A
+{
+  char a[10];
+  int b;
+  char c[10];
+};
+
+void
+__attribute__ ((noinline))
+test1 (struct A *p)
+{
+  char *c;
+  if (__builtin_object_size (&p->a, 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&p->a[0], 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&p->a[3], 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&p->b, 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&p->c, 0) != (size_t) -1)
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 0) != (size_t) -1)
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 0) != (size_t) -1)
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 0) != (size_t) -1)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 0) != (size_t) -1)
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
+    abort ();
+  if (__builtin_object_size (&p->c, 1) != (size_t) -1)
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 1) != sizeof (p->a))
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 1) != sizeof (p->a))
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 1) != sizeof (p->b))
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&p->a, 2) != 0)
+    abort ();
+  if (__builtin_object_size (&p->a[0], 2) != 0)
+    abort ();
+  if (__builtin_object_size (&p->a[3], 2) != 0)
+    abort ();
+  if (__builtin_object_size (&p->b, 2) != 0)
+    abort ();
+  if (__builtin_object_size (&p->c, 2) != 0)
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 2) != 0)
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 2) != 0)
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 2) != 0)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 2) != 0)
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 2) != 0)
+    abort ();
+  if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
+    abort ();
+  if (__builtin_object_size (&p->c, 3) != 0)
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 3) != sizeof (p->a))
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 3) != sizeof (p->a))
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 3) != sizeof (p->b))
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 3) != 0)
+    abort ();
+}
+
+void
+__attribute__ ((noinline))
+test2 (void)
+{
+  char *c;
+  size_t s = 2 * sizeof (struct A);
+  struct A *p = malloc (2 * sizeof (struct A));
+  if (__builtin_object_size (&p->a, 0) != s)
+    abort ();
+  if (__builtin_object_size (&p->a[0], 0) != s)
+    abort ();
+  if (__builtin_object_size (&p->a[3], 0) != s - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
+    abort ();
+  if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 0) != s)
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 0) != s)
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 0) != s - 3)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, b))
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
+    abort ();
+  if (__builtin_object_size (&p->c, 1) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 1) != sizeof (p->a))
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 1) != sizeof (p->a))
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 1) != sizeof (p->b))
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 1) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  if (__builtin_object_size (&p->a, 2) != s)
+    abort ();
+  if (__builtin_object_size (&p->a[0], 2) != s)
+    abort ();
+  if (__builtin_object_size (&p->a[3], 2) != s - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 2) != s - __builtin_offsetof (struct A, b))
+    abort ();
+  if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 2) != s)
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 2) != s)
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 2) != s - 3)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, b))
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
+    abort ();
+  if (__builtin_object_size (&p->c, 3) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  c = p->a;
+  if (__builtin_object_size (c, 3) != sizeof (p->a))
+    abort ();
+  c = &p->a[0];
+  if (__builtin_object_size (c, 3) != sizeof (p->a))
+    abort ();
+  c = &p->a[3];
+  if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
+    abort ();
+  c = (char *) &p->b;
+  if (__builtin_object_size (c, 3) != sizeof (p->b))
+    abort ();
+  c = (char *) &p->c;
+  if (__builtin_object_size (c, 3) != s - __builtin_offsetof (struct A, c))
+    abort ();
+  free (p);
+}
+
+void
+__attribute__ ((noinline))
+test3 (void)
+{
+  char *c;
+  size_t s;
+  struct A *p = malloc (4);
+  if (__builtin_object_size (&p->a, 0) != 4)
+    abort ();
+  if (__builtin_object_size (&p->a[0], 0) != 4)
+    abort ();
+  if (__builtin_object_size (&p->a[3], 0) != 1)
+    abort ();
+  if (__builtin_object_size (&p->b, 0) != 0)
+    abort ();
+  if (__builtin_object_size (&p->c, 0) != 0)
+    abort ();
+  if (__builtin_object_size (&p->a, 1) != 4)
+    abort ();
+  if (__builtin_object_size (&p->a[0], 1) != 4)
+    abort ();
+  if (__builtin_object_size (&p->a[3], 1) != 1)
+    abort ();
+  if (__builtin_object_size (&p->b, 1) != 0)
+    abort ();
+  if (__builtin_object_size (&p->c, 1) != 0)
+    abort ();
+  free (p);
+  s = __builtin_offsetof (struct A, c) + 4;
+  p = malloc (s);
+  if (__builtin_object_size (&p->a, 0) != s)
+    abort ();
+  if (__builtin_object_size (&p->a[0], 0) != s)
+    abort ();
+  if (__builtin_object_size (&p->a[3], 0) != s - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
+    abort ();
+  if (__builtin_object_size (&p->c, 0) != 4)
+    abort ();
+  if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
+    abort ();
+  if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
+    abort ();
+  if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
+    abort ();
+  if (__builtin_object_size (&p->c, 1) != 4)
+    abort ();
+  free (p);
+}
+
+struct B
+{
+  struct A a[4];
+};
+
+void
+__attribute__ ((noinline))
+test4 (struct B *q, int i)
+{
+  if (__builtin_object_size (&q->a[2].a[2], 1) != sizeof (q->a[0].a) - 2)
+    abort ();
+  if (__builtin_object_size (&q->a[2].c[2], 1) != sizeof (q->a[0].c) - 2)
+    abort ();
+  if (__builtin_object_size (&q->a[3].a[2], 1) != sizeof (q->a[0].a) - 2)
+    abort ();
+  if (__builtin_object_size (&q->a[3].c[2], 1) != sizeof (q->a[0].c) - 2)
+    abort ();
+  if (__builtin_object_size (&q->a[i].a[2], 1) != sizeof (q->a[0].a) - 2)
+    abort ();
+  if (__builtin_object_size (&q->a[i].c[2], 1) != sizeof (q->a[0].c) - 2)
+    abort ();
+}
+
+struct C
+{
+  char a[10];
+  char b;
+};
+
+void
+__attribute__ ((noinline))
+test5 (struct C *c)
+{
+  if (__builtin_object_size (&c->b, 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&c->b, 1) != 1)
+    abort ();
+  if (__builtin_object_size (&c->b, 2) != 0)
+    abort ();
+  if (__builtin_object_size (&c->b, 3) != 1)
+    abort ();
+}
+
+struct D
+{
+  int i;
+  struct D1
+  {
+    char b;
+    char a[10];
+  } j;
+};
+
+void
+__attribute__ ((noinline))
+test6 (struct D *d)
+{
+  if (__builtin_object_size (&d->j.a[3], 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&d->j.a[3], 1) != sizeof (d->j.a) - 3)
+    abort ();
+  if (__builtin_object_size (&d->j.a[3], 2) != 0)
+    abort ();
+  if (__builtin_object_size (&d->j.a[3], 3) != sizeof (d->j.a) - 3)
+    abort ();
+}
+
+struct E
+{
+  int i;
+  struct E1
+  {
+    char b;
+    char a[10];
+  } j[1];
+};
+
+void
+__attribute__ ((noinline))
+test7 (struct E *e)
+{
+  if (__builtin_object_size (&e->j[0].a[3], 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&e->j[0].a[3], 1) != sizeof (e->j[0].a) - 3)
+    abort ();
+  if (__builtin_object_size (&e->j[0].a[3], 2) != 0)
+    abort ();
+  if (__builtin_object_size (&e->j[0].a[3], 3) != sizeof (e->j[0].a) - 3)
+    abort ();
+  if (__builtin_object_size ((char *) &e->j[0], 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size ((char *) &e->j[0], 1) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size ((char *) &e->j[0], 2) != 0)
+    abort ();
+  if (__builtin_object_size ((char *) &e->j[0], 3) != 0)
+    abort ();
+}
+
+union F
+{
+  char a[1];
+  struct F1
+  {
+    char b;
+    char c[10];
+  } d;
+};
+
+void
+__attribute__ ((noinline))
+test8 (union F *f)
+{
+  if (__builtin_object_size (&f->d.c[3], 0) != (size_t) -1)
+    abort ();
+  if (__builtin_object_size (&f->d.c[3], 1) != sizeof (f->d.c) - 3)
+    abort ();
+  if (__builtin_object_size (&f->d.c[3], 2) != 0)
+    abort ();
+  if (__builtin_object_size (&f->d.c[3], 3) != sizeof (f->d.c) - 3)
+    abort ();
+}
+
+int
+main (void)
+{
+  struct A a, *p = &a;
+  int i = 1;
+  __asm ("" : "+r" (p));
+  test1 (p);
+  test2 ();
+  test3 ();
+  struct B b, *q = &b;
+  __asm ("" : "+r" (q), "+r" (i));
+  test4 (q, i);
+  struct C c, *cp = &c;
+  __asm ("" : "+r" (cp));
+  test5 (cp);
+  struct D d, *dp = &d;
+  __asm ("" : "+r" (dp));
+  test6 (dp);
+  struct E e, *ep = &e;
+  __asm ("" : "+r" (ep));
+  test7 (ep);
+  union F f, *fp = &f;
+  __asm ("" : "+r" (fp));
+  test8 (fp);
+  exit (0);
+}
--- gcc/tree-object-size.c	(revision 148278)
+++ gcc/tree-object-size.c	(revision 148279)
@@ -43,7 +43,8 @@ struct object_size_info
 static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
 
 static tree compute_object_offset (const_tree, const_tree);
-static unsigned HOST_WIDE_INT addr_object_size (const_tree, int);
+static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *,
+						const_tree, int);
 static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int);
 static tree pass_through_call (const_gimple);
 static void collect_object_sizes_for (struct object_size_info *, tree);
@@ -152,9 +153,10 @@ compute_object_offset (const_tree expr, 
    If unknown, return unknown[object_size_type].  */
 
 static unsigned HOST_WIDE_INT
-addr_object_size (const_tree ptr, int object_size_type)
+addr_object_size (struct object_size_info *osi, const_tree ptr,
+		  int object_size_type)
 {
-  tree pt_var;
+  tree pt_var, pt_var_size = NULL_TREE, var_size, bytes;
 
   gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);
 
@@ -163,58 +165,170 @@ addr_object_size (const_tree ptr, int ob
     pt_var = get_base_address (pt_var);
 
   if (pt_var
-      && (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
-      && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
-      && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
-      && (unsigned HOST_WIDE_INT)
-	 tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1) < offset_limit)
+      && TREE_CODE (pt_var) == INDIRECT_REF
+      && TREE_CODE (TREE_OPERAND (pt_var, 0)) == SSA_NAME
+      && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (pt_var, 0))))
+    {
+      unsigned HOST_WIDE_INT sz;
+
+      if (!osi)
+	sz = compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
+					  object_size_type);
+      else
+	{
+	  tree var = TREE_OPERAND (pt_var, 0);
+	  if (osi->pass == 0)
+	    collect_object_sizes_for (osi, var);
+	  if (bitmap_bit_p (computed[object_size_type],
+			    SSA_NAME_VERSION (var)))
+	    sz = object_sizes[object_size_type][SSA_NAME_VERSION (var)];
+	  else
+	    sz = unknown[object_size_type];
+	}
+
+      if (sz != unknown[object_size_type] && sz < offset_limit)
+	pt_var_size = size_int (sz);
+    }
+  else if (pt_var
+	   && (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
+	   && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
+	   && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
+	   && (unsigned HOST_WIDE_INT)
+	      tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
+	      < offset_limit)
+    pt_var_size = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
+  else
+    return unknown[object_size_type];
+
+  if (pt_var != TREE_OPERAND (ptr, 0))
     {
-      tree bytes;
+      tree var;
 
-      if (pt_var != TREE_OPERAND (ptr, 0))
+      if (object_size_type & 1)
 	{
-	  tree var;
+	  var = TREE_OPERAND (ptr, 0);
 
-	  if (object_size_type & 1)
+	  while (var != pt_var
+		 && TREE_CODE (var) != BIT_FIELD_REF
+		 && TREE_CODE (var) != COMPONENT_REF
+		 && TREE_CODE (var) != ARRAY_REF
+		 && TREE_CODE (var) != ARRAY_RANGE_REF
+		 && TREE_CODE (var) != REALPART_EXPR
+		 && TREE_CODE (var) != IMAGPART_EXPR)
+	    var = TREE_OPERAND (var, 0);
+	  if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
+	      var = TREE_OPERAND (var, 0);
+	  if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
+	      || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
+	      || (pt_var_size
+		  && tree_int_cst_lt (pt_var_size,
+				      TYPE_SIZE_UNIT (TREE_TYPE (var)))))
+	    var = pt_var;
+	  else if (var != pt_var && TREE_CODE (pt_var) == INDIRECT_REF)
 	    {
-	      var = TREE_OPERAND (ptr, 0);
-
-	      while (var != pt_var
-		      && TREE_CODE (var) != BIT_FIELD_REF
-		      && TREE_CODE (var) != COMPONENT_REF
-		      && TREE_CODE (var) != ARRAY_REF
-		      && TREE_CODE (var) != ARRAY_RANGE_REF
-		      && TREE_CODE (var) != REALPART_EXPR
-		      && TREE_CODE (var) != IMAGPART_EXPR)
-		var = TREE_OPERAND (var, 0);
-	      if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
-		var = TREE_OPERAND (var, 0);
-	      if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
-		  || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
-		  || tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)),
-				      TYPE_SIZE_UNIT (TREE_TYPE (var))))
+	      tree v = var;
+	      /* For &X->fld, compute object size only if fld isn't the last
+		 field, as struct { int i; char c[1]; } is often used instead
+		 of flexible array member.  */
+	      while (v && v != pt_var)
+		switch (TREE_CODE (v))
+		  {
+		  case ARRAY_REF:
+		    if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0)))
+			&& TREE_CODE (TREE_OPERAND (v, 1)) == INTEGER_CST)
+		      {
+			tree domain
+			  = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (v, 0)));
+			if (domain
+			    && TYPE_MAX_VALUE (domain)
+			    && TREE_CODE (TYPE_MAX_VALUE (domain))
+			       == INTEGER_CST
+			    && tree_int_cst_lt (TREE_OPERAND (v, 1),
+						TYPE_MAX_VALUE (domain)))
+			  {
+			    v = NULL_TREE;
+			    break;
+			  }
+		      }
+		    v = TREE_OPERAND (v, 0);
+		    break;
+		  case REALPART_EXPR:
+		  case IMAGPART_EXPR:
+		    v = NULL_TREE;
+		    break;
+		  case COMPONENT_REF:
+		    if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+			 == RECORD_TYPE
+			 && TREE_CHAIN (TREE_OPERAND (v, 1)))
+			|| TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
+		      v = NULL_TREE;
+		    else
+		      {
+			if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+			    == RECORD_TYPE)
+			  v = TREE_OPERAND (v, 0);
+			while (v && v != pt_var && TREE_CODE (v) == COMPONENT_REF)
+			  if (TREE_CODE (TREE_TYPE (v)) != UNION_TYPE
+			      && TREE_CODE (TREE_TYPE (v)) != QUAL_UNION_TYPE)
+			    break;
+			  else
+			    v = TREE_OPERAND (v, 0);
+			if (v && v != pt_var)
+			  v = NULL_TREE;
+			else
+			  v = pt_var;
+		      }
+		    break;
+		  default:
+		    v = pt_var;
+		    break;
+		  }
+	      if (v == pt_var)
 		var = pt_var;
 	    }
-	  else
-	    var = pt_var;
+	}
+      else
+	var = pt_var;
 
-	  bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
-	  if (bytes != error_mark_node)
+      if (var != pt_var)
+	var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
+      else if (!pt_var_size)
+	return unknown[object_size_type];
+      else
+	var_size = pt_var_size;
+      bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
+      if (bytes != error_mark_node)
+	{
+	  if (TREE_CODE (bytes) == INTEGER_CST
+	      && tree_int_cst_lt (var_size, bytes))
+	    bytes = size_zero_node;
+	  else
+	    bytes = size_binop (MINUS_EXPR, var_size, bytes);
+	}
+      if (var != pt_var
+	  && pt_var_size
+	  && TREE_CODE (pt_var) == INDIRECT_REF
+	  && bytes != error_mark_node)
+	{
+	  tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
+	  if (bytes2 != error_mark_node)
 	    {
-	      if (TREE_CODE (bytes) == INTEGER_CST
-		  && tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes))
-		bytes = size_zero_node;
+	      if (TREE_CODE (bytes2) == INTEGER_CST
+		  && tree_int_cst_lt (pt_var_size, bytes2))
+		bytes2 = size_zero_node;
 	      else
-		bytes = size_binop (MINUS_EXPR,
-				    TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes);
+		bytes2 = size_binop (MINUS_EXPR, var_size, bytes2);
+	      bytes = size_binop (MIN_EXPR, bytes, bytes2);
 	    }
 	}
-      else
-	bytes = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
-
-      if (host_integerp (bytes, 1))
-	return tree_low_cst (bytes, 1);
     }
+  else if (!pt_var_size)
+    return unknown[object_size_type];
+  else
+    bytes = pt_var_size;
+
+  if (host_integerp (bytes, 1))
+    return tree_low_cst (bytes, 1);
 
   return unknown[object_size_type];
 }
@@ -332,11 +446,11 @@ compute_builtin_object_size (tree ptr, i
     init_offset_limit ();
 
   if (TREE_CODE (ptr) == ADDR_EXPR)
-    return addr_object_size (ptr, object_size_type);
+    return addr_object_size (NULL, ptr, object_size_type);
 
   if (TREE_CODE (ptr) == SSA_NAME
-	   && POINTER_TYPE_P (TREE_TYPE (ptr))
-	   && object_sizes[object_size_type] != NULL)
+      && POINTER_TYPE_P (TREE_TYPE (ptr))
+      && object_sizes[object_size_type] != NULL)
     {
       if (!bitmap_bit_p (computed[object_size_type], SSA_NAME_VERSION (ptr)))
 	{
@@ -477,7 +591,7 @@ expr_object_size (struct object_size_inf
 	      || !POINTER_TYPE_P (TREE_TYPE (value)));
 
   if (TREE_CODE (value) == ADDR_EXPR)
-    bytes = addr_object_size (value, object_size_type);
+    bytes = addr_object_size (osi, value, object_size_type);
   else
     bytes = unknown[object_size_type];
 
@@ -633,7 +747,7 @@ plus_stmt_object_size (struct object_siz
 	  unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
 
           /* op0 will be ADDR_EXPR here.  */
-	  bytes = compute_builtin_object_size (op0, object_size_type);
+	  bytes = addr_object_size (osi, op0, object_size_type);
 	  if (bytes == unknown[object_size_type])
 	    ;
 	  else if (off > offset_limit)

gcc44-epilogue-unwind.patch:

--- NEW FILE gcc44-epilogue-unwind.patch ---
2009-06-08  Jakub Jelinek  <jakub at redhat.com>

	* dwarf2out.c (emit_cfa_remember): New variable.
	(add_fde_cfi): If emit_cfa_remember, recurse to add
	DW_CFA_remember_state first.
	(dwarf2out_begin_epilogue): Don't add_fde_cfi DW_CFA_remember_state,
	instead just set emit_cfa_remember.

2009-06-08  Adam Nemet  <anemet at caviumnetworks.com>

	* jump.c (returnjump_p): Handle delayed branches.  Add missing
	function comment.

2009-06-05  Nathan Froyd  <froydnj at codesourcery.com>

	* config/rs6000/ppc-asm.h: Protect auto-host.h inclusion and
	CFI_* definitions with IN_GCC.

2009-06-04  Jakub Jelinek  <jakub at redhat.com>

	* config/s390/s390.c (global_not_special_regno_p): New static inline.
	(save_gprs): Don't tell unwinder when a global register is saved.
	(s390_emit_epilogue): Emit needed epilogue unwind info.

2009-06-03  Jakub Jelinek  <jakub at redhat.com>

	* config/rs6000/rs6000.c (rs6000_emit_stack_reset): Return generated
	insn if it is changing sp.  Use gen_add3_insn instead of
	conditionally gen_addsi3 and gen_adddi3.
	(offset_below_red_zone_p): New static inline function.
	(rs6000_emit_epilogue): Emit needed epilogue unwind info.
	Use gen_add3_insn instead of conditionally gen_addsi3 and gen_adddi3.
	* config/rs6000/ppc-asm.h: Include auto-host.h.
	(CFI_STARTPROC, CFI_ENDPROC, CFI_DEF_CFA_REGISTER, CFI_OFFSET,
	CFI_RESTORE): Define.
	* config/rs6000/crtresxgpr.asm: Add unwind info.
	* config/rs6000/crtresxfpr.asm: Likewise.
	* config/rs6000/crtresgpr.asm: Likewise.
	* config/rs6000/crtresfpr.asm: Likewise.
	* config/rs6000/crtsavgpr.asm: Likewise.
	* config/rs6000/crtsavfpr.asm: Likewise.

2009-06-01  Jakub Jelinek  <jakub at redhat.com>

	* config/i386/i386.c (queued_cfa_restores): New static variable.
	(ix86_add_cfa_restore_note, ix86_add_queued_cfa_restore_notes): New
	functions.
	(pro_epilogue_adjust_stack): Call ix86_add_queued_cfa_restore_notes.
	(ix86_emit_restore_reg_using_pop): Add RED_OFFSET argument.
	Set RTX_FRAME_RELATED_P immediately after adding a REG_CFA_* note.
	Call ix86_add_cfa_restore_note instead of adding REG_CFA_OFFSET
	note unconditionally.
	(ix86_emit_restore_regs_using_mov): Likewise.
	(ix86_emit_restore_sse_regs_using_mov): Likewise.
	(ix86_emit_restore_regs_using_pop): Add RED_OFFSET argument, pass
	it through to ix86_emit_restore_reg_using_pop.
	(ix86_emit_leave): Add RED_OFFSET argument.  Call
	ix86_add_queued_cfa_restore_notes.  Call ix86_add_cfa_restore_note
	instead of adding REG_CFA_OFFSET note unconditionally.
	(ix86_expand_epilogue): Compute RED_OFFSET, pass it down to
	the above functions.  Call ix86_add_queued_cfa_restore_notes when
	needed.

	* config/i386/i386.h (struct machine_cfa_state,
	struct machine_function): Guard with ifndef USED_FOR_TARGET
	instead of not IN_LIBGCC2 and not in IN_TARGET_LIBS.

	PR middle-end/40316
	* recog.c (peep2_reinit_state): New function.
	(peephole2_init_state): Use it at the end of a basic block and also
	when seeing a RTX_FRAME_RELATED_P insn.

2009-05-31  Jakub Jelinek  <jakub at redhat.com>

	PR middle-end/40304
	* config/i386/i386.c (pro_epilogue_adjust_stack): Mark insns
	frame related even if !set_cfa && style < 0.

2009-05-29  Richard Henderson  <rth at redhat.com>

	* cfgcleanup.c (try_crossjump_to_edge): Only skip past
	NOTE_INSN_BASIC_BLOCK.
	* cfglayout.c (duplicate_insn_chain): Copy epilogue insn marks.
	Duplicate NOTE_INSN_EPILOGUE_BEG notes.
	* cfgrtl.c (can_delete_note_p): Allow NOTE_INSN_EPILOGUE_BEG
	to be deleted.
	* dwarf2out.c (struct cfa_loc): Change indirect field to bitfield,
	add in_use field.
	(add_cfi): Disable check redefining cfa away from drap.
	(lookup_cfa_1): Add remember argument; handle remember/restore.
	(lookup_cfa): Pass remember argument.
	(cfa_remember): New.
	(compute_barrier_args_size_1): Remove sibcall check.
	(dwarf2out_frame_debug_def_cfa): New.
	(dwarf2out_frame_debug_adjust_cfa): New.
	(dwarf2out_frame_debug_cfa_offset): New.
	(dwarf2out_frame_debug_cfa_register): New.
	(dwarf2out_frame_debug_cfa_restore): New.
	(dwarf2out_frame_debug): Handle REG_CFA_* notes.
	(dwarf2out_begin_epilogue): New.
	(dwarf2out_frame_debug_restore_state): New.
	(dw_cfi_oprnd1_desc): Handle DW_CFA_remember_state,
	DW_CFA_restore_state.
	(output_cfi_directive): Likewise.
	(convert_cfa_to_fb_loc_list): Likewise.
	(dw_cfi_oprnd1_desc): Handle DW_CFA_restore.
	* dwarf2out.h: Update.
	* emit-rtl.c (try_split): Don't split RTX_FRAME_RELATED_P.
	(copy_insn_1): Early out for null.
	* final.c (final_scan_insn): Call dwarf2out_begin_epilogue
	and dwarf2out_frame_debug_restore_state.
	* function.c (prologue, epilogue, sibcall_epilogue): Remove.
	(prologue_insn_hash, epilogue_insn_hash): New.
	(free_after_compilation): Adjust freeing accordingly.
	(record_insns): Create hash table if needed; push insns into
	hash instead of array.
	(maybe_copy_epilogue_insn): New.
	(contains): Search hash table instead of array.
	(sibcall_epilogue_contains): Remove.
	(thread_prologue_and_epilogue_insns): Split eh_return insns
	and mark them as epilogues.
	(reposition_prologue_and_epilogue_notes): Rewrite epilogue
	scanning in terms of basic blocks.
	* insn-notes.def (CFA_RESTORE_STATE): New.
	* jump.c (returnjump_p_1): Accept EH_RETURN.
	(eh_returnjump_p_1, eh_returnjump_p): New.
	* reg-notes.def (CFA_DEF_CFA, CFA_ADJUST_CFA, CFA_OFFSET,
	CFA_REGISTER, CFA_RESTORE): New.
	* rtl.def (EH_RETURN): New.
	* rtl.h (eh_returnjump_p, maybe_copy_epilogue_insn): Declare.

	* config/bfin/bfin.md (UNSPEC_VOLATILE_EH_RETURN): Remove.
	(eh_return_internal): Use eh_return rtx; split w/ epilogue.

	* config/i386/i386.c (gen_push): Update cfa state.
	(pro_epilogue_adjust_stack): Add set_cfa argument.  When true,
	add a CFA_ADJUST_CFA note.
	(ix86_dwarf_handle_frame_unspec): Remove.
	(ix86_expand_prologue): Update cfa state.
	(ix86_emit_restore_reg_using_pop): New.
	(ix86_emit_restore_regs_using_pop): New.
	(ix86_emit_leave): New.
	(ix86_emit_restore_regs_using_mov): Add CFA_RESTORE notes.
	(ix86_expand_epilogue): Add notes for unwinding the epilogue.
	* config/i386/i386.h (struct machine_cfa_state): New.
	(ix86_cfa_state): New.
	* config/i386/i386.md (UNSPEC_EH_RETURN): Remove.
	(eh_return_internal): Merge from eh_return_<mode>,
	use eh_return rtx, split w/ epilogue.

--- gcc/rtl.def.jj	2009-01-14 12:06:29.000000000 +0100
+++ gcc/rtl.def	2009-06-09 08:58:04.000000000 +0200
@@ -281,6 +281,10 @@ DEF_RTL_EXPR(CALL, "call", "ee", RTX_EXT
 
 DEF_RTL_EXPR(RETURN, "return", "", RTX_EXTRA)
 
+/* Special for EH return from subroutine.  */
+
+DEF_RTL_EXPR(EH_RETURN, "eh_return", "", RTX_EXTRA)
+
 /* Conditional trap.
    Operand 1 is the condition.
    Operand 2 is the trap code.
--- gcc/cfglayout.c.jj	2009-01-14 12:06:29.000000000 +0100
+++ gcc/cfglayout.c	2009-06-09 08:58:04.000000000 +0200
@@ -1112,7 +1112,7 @@ cfg_layout_can_duplicate_bb_p (const_bas
 rtx
 duplicate_insn_chain (rtx from, rtx to)
 {
-  rtx insn, last;
+  rtx insn, last, copy;
 
   /* Avoid updating of boundaries of previous basic block.  The
      note will get removed from insn stream in fixup.  */
@@ -1133,7 +1133,8 @@ duplicate_insn_chain (rtx from, rtx to)
 	  if (GET_CODE (PATTERN (insn)) == ADDR_VEC
 	      || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
 	    break;
-	  emit_copy_of_insn_after (insn, get_last_insn ());
+	  copy = emit_copy_of_insn_after (insn, get_last_insn ());
+          maybe_copy_epilogue_insn (insn, copy);
 	  break;
 
 	case CODE_LABEL:
@@ -1153,23 +1154,18 @@ duplicate_insn_chain (rtx from, rtx to)
 	    case NOTE_INSN_DELETED:
 	    case NOTE_INSN_DELETED_LABEL:
 	      /* No problem to strip these.  */
-	    case NOTE_INSN_EPILOGUE_BEG:
-	      /* Debug code expect these notes to exist just once.
-		 Keep them in the master copy.
-		 ??? It probably makes more sense to duplicate them for each
-		 epilogue copy.  */
 	    case NOTE_INSN_FUNCTION_BEG:
 	      /* There is always just single entry to function.  */
 	    case NOTE_INSN_BASIC_BLOCK:
 	      break;
 
+	    case NOTE_INSN_EPILOGUE_BEG:
[...2708 lines suppressed...]
@@ -5058,6 +5062,9 @@ copy_insn_1 (rtx orig)
   RTX_CODE code;
   const char *format_ptr;
 
+  if (orig == NULL)
+    return NULL;
+
   code = GET_CODE (orig);
 
   switch (code)
--- gcc/dwarf2out.h.jj	2009-01-14 12:06:29.000000000 +0100
+++ gcc/dwarf2out.h	2009-06-09 08:58:04.000000000 +0200
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  
 
 extern void dwarf2out_decl (tree);
 extern void dwarf2out_frame_debug (rtx, bool);
+extern void dwarf2out_begin_epilogue (rtx);
+extern void dwarf2out_frame_debug_restore_state (void);
 
 extern void debug_dwarf (void);
 struct die_struct;
--- gcc/final.c.jj	2009-01-14 12:06:29.000000000 +0100
+++ gcc/final.c	2009-06-09 08:58:04.000000000 +0200
@@ -1869,9 +1869,19 @@ final_scan_insn (rtx insn, FILE *file, i
 	  break;
 
 	case NOTE_INSN_EPILOGUE_BEG:
+#if defined (DWARF2_UNWIND_INFO) && defined (HAVE_epilogue)
+	  if (dwarf2out_do_frame ())
+	    dwarf2out_begin_epilogue (insn);
+#endif
 	  targetm.asm_out.function_begin_epilogue (file);
 	  break;
 
+	case NOTE_INSN_CFA_RESTORE_STATE:
+#if defined (DWARF2_UNWIND_INFO)
+	  dwarf2out_frame_debug_restore_state ();
+#endif
+	  break;
+
 	case NOTE_INSN_FUNCTION_BEG:
 	  app_disable ();
 	  (*debug_hooks->end_prologue) (last_linenum, last_filename);
--- gcc/jump.c.jj	2009-03-04 12:10:22.000000000 +0100
+++ gcc/jump.c	2009-06-09 09:20:50.000000000 +0200
@@ -869,18 +869,54 @@ returnjump_p_1 (rtx *loc, void *data ATT
 {
   rtx x = *loc;
 
-  return x && (GET_CODE (x) == RETURN
-	       || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
+  if (x == NULL)
+    return false;
+
+  switch (GET_CODE (x))
+    {
+    case RETURN:
+    case EH_RETURN:
+      return true;
+
+    case SET:
+      return SET_IS_RETURN_P (x);
+
+    default:
+      return false;
+    }
 }
 
+/* Return TRUE if INSN is a return jump.  */
+
 int
 returnjump_p (rtx insn)
 {
+  /* Handle delayed branches.  */
+  if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
+    insn = XVECEXP (PATTERN (insn), 0, 0);
+
   if (!JUMP_P (insn))
     return 0;
+
   return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
 }
 
+/* Return true if INSN is a (possibly conditional) return insn.  */
+
+static int
+eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
+{
+  return *loc && GET_CODE (*loc) == EH_RETURN;
+}
+
+int
+eh_returnjump_p (rtx insn)
+{
+  if (!JUMP_P (insn))
+    return 0;
+  return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL);
+}
+
 /* Return true if INSN is a jump that only transfers control and
    nothing more.  */
 
--- gcc/recog.c.jj	2009-03-10 11:06:10.000000000 +0100
+++ gcc/recog.c	2009-06-09 09:08:21.000000000 +0200
@@ -3026,6 +3026,26 @@ peep2_find_free_register (int from, int 
   return NULL_RTX;
 }
 
+/* Forget all currently tracked instructions, only remember current
+   LIVE regset.  */
+
+static void
+peep2_reinit_state (regset live)
+{
+  int i;
+
+  /* Indicate that all slots except the last holds invalid data.  */
+  for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
+    peep2_insn_data[i].insn = NULL_RTX;
+  peep2_current_count = 0;
+
+  /* Indicate that the last slot contains live_after data.  */
+  peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
+  peep2_current = MAX_INSNS_PER_PEEP2;
+
+  COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
+}
+
 /* Perform the peephole2 optimization pass.  */
 
 static void
@@ -3049,19 +3069,11 @@ peephole2_optimize (void)
   FOR_EACH_BB_REVERSE (bb)
     {
       rtl_profile_for_bb (bb);
-      /* Indicate that all slots except the last holds invalid data.  */
-      for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
-	peep2_insn_data[i].insn = NULL_RTX;
-      peep2_current_count = 0;
-
-      /* Indicate that the last slot contains live_after data.  */
-      peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
-      peep2_current = MAX_INSNS_PER_PEEP2;
 
       /* Start up propagation.  */
       bitmap_copy (live, DF_LR_OUT (bb));
       df_simulate_initialize_backwards (bb, live);
-      bitmap_copy (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
+      peep2_reinit_state (live);
 
       for (insn = BB_END (bb); ; insn = prev)
 	{
@@ -3088,7 +3100,7 @@ peephole2_optimize (void)
 		  /* If an insn has RTX_FRAME_RELATED_P set, peephole
 		     substitution would lose the
 		     REG_FRAME_RELATED_EXPR that is attached.  */
-		  peep2_current_count = 0;
+		  peep2_reinit_state (live);
 		  attempt = NULL;
 		}
 	      else
--- gcc/rtl.h.jj	2009-04-27 13:57:11.000000000 +0200
+++ gcc/rtl.h	2009-06-09 08:58:04.000000000 +0200
@@ -2072,6 +2072,7 @@ extern rtx pc_set (const_rtx);
 extern rtx condjump_label (const_rtx);
 extern int simplejump_p (const_rtx);
 extern int returnjump_p (rtx);
+extern int eh_returnjump_p (rtx);
 extern int onlyjump_p (const_rtx);
 extern int only_sets_cc0_p (const_rtx);
 extern int sets_cc0_p (const_rtx);
@@ -2185,6 +2186,7 @@ extern int prologue_epilogue_contains (c
 extern int sibcall_epilogue_contains (const_rtx);
 extern void mark_temp_addr_taken (rtx);
 extern void update_temp_slot_address (rtx, rtx);
+extern void maybe_copy_epilogue_insn (rtx, rtx);
 
 /* In stmt.c */
 extern void expand_null_return (void);
--- gcc/cfgrtl.c.jj	2009-06-09 08:16:10.000000000 +0200
+++ gcc/cfgrtl.c	2009-06-09 08:58:05.000000000 +0200
@@ -87,8 +87,16 @@ static void rtl_make_forwarder_block (ed
 static int
 can_delete_note_p (const_rtx note)
 {
-  return (NOTE_KIND (note) == NOTE_INSN_DELETED
-	  || NOTE_KIND (note) == NOTE_INSN_BASIC_BLOCK);
+  switch (NOTE_KIND (note))
+    {
+    case NOTE_INSN_DELETED:
+    case NOTE_INSN_BASIC_BLOCK:
+    case NOTE_INSN_EPILOGUE_BEG:
+      return true;
+
+    default:
+      return false;
+    }
 }
 
 /* True if a given label can be deleted.  */

gcc44-ix86-insn-length.patch:

--- NEW FILE gcc44-ix86-insn-length.patch ---
2009-05-29  Jakub Jelinek  <jakub at redhat.com>

	* config/i386/i386.c (ix86_decompose_address): Avoid useless
	0 displacement.  Add 0 displacement if base is %[er]bp or %r13.

	* config/i386/i386.md (prefix_data16, prefix_rep): Set to 0 for
	TYPE_SSE{MULADD,4ARG,IADD1,CVT1} by default.
	(prefix_rex): For UNIT_MMX don't imply the prefix by default
	if MODE_DI.
	(prefix_extra): Default to 2 for TYPE_SSE{MULADD,4ARG} and
	to 1 for TYPE_SSE{IADD1,CVT1}.
	(prefix_vex_imm8): Removed.
	(length_vex): Only pass 1 as second argument to
	ix86_attr_length_vex_default if prefix_extra is 0.
	(modrm): For TYPE_INCDEC only set to 0 if not TARGET_64BIT.
	(length): For prefix vex computation use length_immediate
	attribute instead of prefix_vex_imm8.
	(cmpqi_ext_3_insn, cmpqi_ext_3_insn_rex64,
	addqi_ext_1, addqi_ext_1_rex64, *testqi_ext_0, andqi_ext_0,
	*andqi_ext_0_cc, *iorqi_ext_0, *xorqi_ext_0, *xorqi_cc_ext_1,
	*xorqi_cc_ext_1_rex64): Override modrm attribute to 1.
	(extendsidi2_rex64, extendhidi2, extendqidi2, extendhisi2,
	*extendhisi2_zext, extendqihi2, extendqisi2, *extendqisi2_zext): Emit
	a space in between the operands.
	(*anddi_1_rex64, *andsi_1): Likewise.  Override prefix_rex to 1
	if one operand is 0xff and the other one si, di, bp or sp.
	(*andhi_1): Override prefix_rex to 1 if one operand is 0xff and the
	other one si, di, bp or sp.
	(*btsq, *btrq, *btcq, *btdi_rex64, *btsi): Add mode attribute.
	(*ffssi_1, *ffsdi_1, ctzsi2, ctzdi2): Add
	type and mode attributes.
	(*bsr, *bsr_rex64, *bsrhi): Add type attribute.
	(*cmpfp_i_mixed, *cmpfp_iu_mixed): For TYPE_SSECOMI, clear
	prefix_rep attribute and set prefix_data16 attribute iff MODE_DF.
	(*cmpfp_i_sse, *cmpfp_iu_sse): Clear prefix_rep attribute and set
	prefix_data16 attribute iff MODE_DF.
	(*movsi_1): For TYPE_SSEMOV MODE_SI set prefix_data16 attribute.
	(fix_trunc<mode>di_sse): Set prefix_rex attribute.
	(*adddi_4_rex64, *addsi_4): Use const128_operand instead of
	constm128_operand in length_immediate computation.
	(*addhi_4): Likewise.  Fix mode attribute to MODE_HI.
	(anddi_1_rex64): Use movzbl/movzwl instead of movzbq/movzwq.
	(*avx_ashlti3, sse2_ashlti3, *avx_lshrti3, sse2_lshrti3): Set
	length_immediate attribute to 1.
	(x86_fnstsw_1, x86_fnstcw_1, x86_fldcw_1): Fix length attribute.
	(*movdi_1_rex64): Override prefix_rex or prefix_data16 attributes
	for certain alternatives.
	(*movdf_nointeger, *movdf_integer_rex64, *movdf_integer): Override
	prefix_data16 attribute if MODE_V1DF.
	(*avx_setcc<mode>, *sse_setcc<mode>, *sse5_setcc<mode>): Set
	length_immediate to 1.
	(set_got_rex64, set_rip_rex64): Remove length attribute, set
	length_address to 4, set mode attribute to MODE_DI.
	(set_got_offset_rex64): Likewise.  Set length_immediate to 0.
	(fxam<mode>2_i387): Set length attribute to 4.
	(*prefetch_sse, *prefetch_sse_rex, *prefetch_3dnow,
	*prefetch_3dnow_rex): Override length_address attribute.
	(sse4_2_crc32<mode>): Override prefix_data16 and prefix_rex
	attributes.
	* config/i386/predicates.md (ext_QIreg_nomode_operand): New predicate.
	(constm128_operand): Removed.
	* config/i386/i386.c (memory_address_length): For
	disp && !index && !base in 64-bit mode account for SIB byte if
	print_operand_address can't optimize disp32 into disp32(%rip)
	and UNSPEC doesn't imply (%rip) addressing.  Add 1 to length
	for fs: or gs: segment.
	(ix86_attr_length_immediate_default): When checking if shortform
	is possible, truncate immediate to the length of the non-shortened
	immediate.
	(ix86_attr_length_address_default): Ignore MEM_P operands
	with X constraint.
	(ix86_attr_length_vex_default): Only check for DImode on
	GENERAL_REG_P operands.
	* config/i386/sse.md (<sse>_comi, <sse>_ucomi): Clear
	prefix_rep attribute, set prefix_data16 attribute iff MODE_DF.
	(sse_cvttps2pi): Clear prefix_rep attribute.
	(sse2_cvttps2dq, *sse2_cvtpd2dq, sse2_cvtps2pd): Clear prefix_data16
	attribute.
	(*sse2_cvttpd2dq): Don't clear prefix_rep attribute.
	(*avx_ashr<mode>3, ashr<mode>3, *avx_lshr<mode>3, lshr<mode>3,
	*avx_ashl<mode>3, ashl<mode>3): Set length_immediate attribute to 1
	iff operand 2 is const_int_operand.
	(*vec_dupv4si, avx_shufpd256_1, *avx_shufpd_<mode>,
	sse2_shufpd_<mode>): Set length_immediate attribute to 1.
	(sse2_pshufd_1): Likewise.  Set prefix attribute to maybe_vex
	instead of vex.
	(sse2_pshuflw_1, sse2_pshufhw_1): Set length_immediate to 1 and clear
	prefix_data16.
	(sse2_unpckhpd, sse2_unpcklpd, sse2_storehpd, *vec_concatv2df): Set
	prefix_data16 attribute for movlpd and movhpd instructions.
	(sse2_loadhpd, sse2_loadlpd, sse2_movsd): Likewise.  Override
	length_immediate for shufpd instruction.
	(sse2_movntsi, sse3_lddqu): Clear prefix_data16 attribute.
	(avx_cmpp<avxmodesuffixf2c><mode>3,
	avx_cmps<ssemodesuffixf2c><mode>3, *avx_maskcmp<mode>3,
	<sse>_maskcmp<mode>3, <sse>_vmmaskcmp<mode>3,
	avx_shufps256_1, *avx_shufps_<mode>, sse_shufps_<mode>,
	*vec_dupv4sf_avx, *vec_dupv4sf): Set
	length_immediate attribute to 1.
	(*avx_cvtsi2ssq, *avx_cvtsi2sdq): Set length_vex attribute to 4.
	(sse_cvtsi2ssq, sse2_cvtsi2sdq): Set prefix_rex attribute to 1.
	(sse2_cvtpi2pd, sse_loadlps, sse2_storelpd): Override
	prefix_data16 attribute for the first alternative to 1.
	(*avx_loadlps): Override length_immediate for the first alternative.
	(*vec_concatv2sf_avx): Override length_immediate and prefix_extra
	attributes for second alternative.
	(*vec_concatv2sf_sse4_1): Override length_immediate and
	prefix_data16 attributes for second alternative.
	(*vec_setv4sf_avx, *avx_insertps, vec_extract_lo_<mode>,
	vec_extract_hi_<mode>, vec_extract_lo_v16hi,
	vec_extract_hi_v16hi, vec_extract_lo_v32qi,
	vec_extract_hi_v32qi): Set prefix_extra and length_immediate to 1.
	(*vec_setv4sf_sse4_1, sse4_1_insertps, *sse4_1_extractps): Set
	prefix_data16 and length_immediate to 1.
	(*avx_mulv2siv2di3, *avx_mulv4si3, sse4_2_gtv2di3): Set prefix_extra
	to 1.
	(*avx_<code><mode>3, *avx_eq<mode>3, *avx_gt<mode>3): Set
	prefix_extra attribute for variants that don't have 0f prefix
	alone.
	(*avx_pinsr<ssevecsize>): Likewise.  Set length_immediate to 1.
	(*sse4_1_pinsrb, *sse2_pinsrw, *sse4_1_pinsrd, *sse4_1_pextrb,
	*sse4_1_pextrb_memory, *sse2_pextrw, *sse4_1_pextrw_memory,
	*sse4_1_pextrd): Set length_immediate to 1.
	(*sse4_1_pinsrd): Likewise.  Set prefix_extra to 1.
	(*sse4_1_pinsrq, *sse4_1_pextrq): Set prefix_rex and length_immediate
	to 1.
	(*vec_extractv2di_1_rex64_avx, *vec_extractv2di_1_rex64,
	*vec_extractv2di_1_avx, *vec_extractv2di_1_sse2): Override
	length_immediate to 1 for second alternative.
	(*vec_concatv2si_avx, *vec_concatv2di_rex64_avx): Override
	prefix_extra and length_immediate attributes for the first
	alternative.
	(vec_concatv2si_sse4_1): Override length_immediate to 1 for the
	first alternative.
	(*vec_concatv2di_rex64_sse4_1): Likewise.  Override prefix_rex
	to 1 for the first and third alternative.
	(*vec_concatv2di_rex64_sse): Override prefix_rex to 1 for the second
	alternative.
	(*sse2_maskmovdqu, *sse2_maskmovdqu_rex64): Override length_vex
	attribute.
	(*sse_sfence, sse2_mfence, sse2_lfence): Override length_address
	attribute to 0.
	(*avx_phaddwv8hi3, *avx_phadddv4si3, *avx_phaddswv8hi3,
	*avx_phsubwv8hi3, *avx_phsubdv4si3, *avx_phsubswv8hi,
	*avx_pmaddubsw128, *avx_pmulhrswv8hi3, *avx_pshufbv16qi3,
	*avx_psign<mode>3): Set prefix_extra attribute to 1.
	(ssse3_phaddwv4hi3, ssse3_phadddv2si3, ssse3_phaddswv4hi3,
	ssse3_phsubwv4hi3, ssse3_phsubdv2si3, ssse3_phsubswv4hi3,
	ssse3_pmaddubsw, *ssse3_pmulhrswv4hi, ssse3_pshufbv8qi3,
	ssse3_psign<mode>3): Override prefix_rex attribute.
	(*avx_palignrti): Override prefix_extra and length_immediate
	to 1.
	(ssse3_palignrti): Override length_immediate to 1.
	(ssse3_palignrdi): Override length_immediate to 1, override
	prefix_rex attribute.
	(abs<mode>2): Override prefix_rep to 0, override prefix_rex
	attribute.
	(sse4a_extrqi): Override length_immediate to 2.
	(sse4a_insertqi): Likewise.  Override prefix_data16 to 0.
	(sse4a_insertq): Override prefix_data16 to 0.
	(avx_blendp<avxmodesuffixf2c><avxmodesuffix>,
	avx_blendvp<avxmodesuffixf2c><avxmodesuffix>,
	avx_dpp<avxmodesuffixf2c><avxmodesuffix>, *avx_mpsadbw,
	*avx_pblendvb, *avx_pblendw, avx_roundp<avxmodesuffixf2c>256,
	avx_rounds<avxmodesuffixf2c>256): Override prefix_extra
	and length_immediate to 1.
	(sse4_1_blendp<ssemodesuffixf2c>, sse4_1_dpp<ssemodesuffixf2c>,
	sse4_2_pcmpestr, sse4_2_pcmpestri, sse4_2_pcmpestrm,
	sse4_2_pcmpestr_cconly, sse4_2_pcmpistr, sse4_2_pcmpistri,
	sse4_2_pcmpistrm, sse4_2_pcmpistr_cconly): Override prefix_data16
	and length_immediate to 1.
	(sse4_1_blendvp<ssemodesuffixf2c>): Override prefix_data16 to 1.
	(sse4_1_mpsadbw, sse4_1_pblendw): Override length_immediate to 1.
	(*avx_packusdw, avx_vtestp<avxmodesuffixf2c><avxmodesuffix>,
	avx_ptest256): Override prefix_extra to 1.
	(sse4_1_roundp<ssemodesuffixf2c>, sse4_1_rounds<ssemodesuffixf2c>):
	Override prefix_data16 and length_immediate to 1.
	(sse5_pperm_zero_v16qi_v8hi, sse5_pperm_sign_v16qi_v8hi,
	sse5_pperm_zero_v8hi_v4si, sse5_pperm_sign_v8hi_v4si,
	sse5_pperm_zero_v4si_v2di, sse5_pperm_sign_v4si_v2di,
	sse5_vrotl<mode>3, sse5_ashl<mode>3, sse5_lshl<mode>3): Override
	prefix_data16 to 0 and prefix_extra to 2.
	(sse5_rotl<mode>3, sse5_rotr<mode>3): Override length_immediate to 1.
	(sse5_frcz<mode>2, sse5_vmfrcz<mode>2): Don't override prefix_extra
	attribute.
	(*sse5_vmmaskcmp<mode>3, sse5_com_tf<mode>3,
	sse5_maskcmp<mode>3, sse5_maskcmp<mode>3, sse5_maskcmp_uns<mode>3):
	Override prefix_data16 and prefix_rep to 0, length_immediate to 1
	and prefix_extra to 2.
	(sse5_maskcmp_uns2<mode>3, sse5_pcom_tf<mode>3): Override
	prefix_data16 to 0, length_immediate to 1 and prefix_extra to 2.
	(*avx_aesenc, *avx_aesenclast, *avx_aesdec, *avx_aesdeclast,
	avx_vpermilvar<mode>3,
	avx_vbroadcasts<avxmodesuffixf2c><avxmodesuffix>,
	avx_vbroadcastss256, avx_vbroadcastf128_p<avxmodesuffixf2c>256,
	avx_maskloadp<avxmodesuffixf2c><avxmodesuffix>,
	avx_maskstorep<avxmodesuffixf2c><avxmodesuffix>):
	Override prefix_extra to 1.
	(aeskeygenassist, pclmulqdq): Override length_immediate to 1.
[...4474 lines suppressed...]
+   (set_attr "mode" "SI")])
 
 (define_insn "ctzdi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -15550,7 +15925,9 @@ (define_insn "ctzdi2"
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
   "bsf{q}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")])
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "DI")])
 
 (define_expand "clzsi2"
   [(parallel
@@ -15587,7 +15964,8 @@ (define_insn "*bsr"
    (clobber (reg:CC FLAGS_REG))]
   ""
   "bsr{l}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
    (set_attr "mode" "SI")])
 
 (define_insn "popcount<mode>2"
@@ -15771,7 +16149,8 @@ (define_insn "*bsr_rex64"
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT"
   "bsr{q}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
    (set_attr "mode" "DI")])
 
 (define_expand "clzhi2"
@@ -15809,7 +16188,8 @@ (define_insn "*bsrhi"
    (clobber (reg:CC FLAGS_REG))]
   ""
   "bsr{w}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_0f" "1")
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
    (set_attr "mode" "HI")])
 
 (define_expand "paritydi2"
@@ -18901,6 +19281,7 @@ (define_insn "fxam<mode>2_i387"
   "TARGET_USE_FANCY_MATH_387"
   "fxam\n\tfnstsw\t%0"
   [(set_attr "type" "multi")
+   (set_attr "length" "4")
    (set_attr "unit" "i387")
    (set_attr "mode" "<MODE>")])
 
@@ -19190,6 +19571,7 @@ (define_insn "*strmovqi_rex_1"
   "movsb"
   [(set_attr "type" "str")
    (set_attr "memory" "both")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "rep_mov"
@@ -19446,6 +19828,7 @@ (define_insn "*strsetqi_rex_1"
   "stosb"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "rep_stos"
@@ -19539,6 +19922,7 @@ (define_insn "*rep_stosqi_rex64"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
+   (set_attr "prefix_rex" "0")
    (set_attr "mode" "QI")])
 
 (define_expand "cmpstrnsi"
@@ -19665,6 +20049,7 @@ (define_insn "*cmpstrnqi_nz_rex_1"
   "repz cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set_attr "prefix_rex" "0")
    (set_attr "prefix_rep" "1")])
 
 ;; The same, but the count is not known to not be zero.
@@ -19718,6 +20103,7 @@ (define_insn "*cmpstrnqi_rex_1"
   "repz cmpsb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set_attr "prefix_rex" "0")
    (set_attr "prefix_rep" "1")])
 
 (define_expand "strlensi"
@@ -19779,6 +20165,7 @@ (define_insn "*strlenqi_rex_1"
   "repnz scasb"
   [(set_attr "type" "str")
    (set_attr "mode" "QI")
+   (set_attr "prefix_rex" "0")
    (set_attr "prefix_rep" "1")])
 
 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
@@ -20299,6 +20686,14 @@ (define_insn "pro_epilogue_adjust_stack_
 		 (const_string "imov")
 	      ]
 	      (const_string "lea")))
+   (set (attr "length_immediate")
+	(cond [(eq_attr "type" "imov")
+		 (const_string "0")
+	       (and (eq_attr "type" "alu")
+		    (match_operand 2 "const128_operand" ""))
+		 (const_string "1")
+	      ]
+	      (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "pro_epilogue_adjust_stack_rex64"
@@ -20343,6 +20738,14 @@ (define_insn "pro_epilogue_adjust_stack_
 		 (const_string "imov")
 	      ]
 	      (const_string "lea")))
+   (set (attr "length_immediate")
+	(cond [(eq_attr "type" "imov")
+		 (const_string "0")
+	       (and (eq_attr "type" "alu")
+		    (match_operand 2 "const128_operand" ""))
+		 (const_string "1")
+	      ]
+	      (const_string "*")))
    (set_attr "mode" "DI")])
 
 (define_insn "pro_epilogue_adjust_stack_rex64_2"
@@ -21830,6 +22233,7 @@ (define_insn "*prefetch_sse"
 }
   [(set_attr "type" "sse")
    (set_attr "atom_sse_attr" "prefetch")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_insn "*prefetch_sse_rex"
@@ -21849,6 +22253,7 @@ (define_insn "*prefetch_sse_rex"
 }
   [(set_attr "type" "sse")
    (set_attr "atom_sse_attr" "prefetch")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_insn "*prefetch_3dnow"
@@ -21863,6 +22268,7 @@ (define_insn "*prefetch_3dnow"
     return "prefetchw\t%a0";
 }
   [(set_attr "type" "mmx")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_insn "*prefetch_3dnow_rex"
@@ -21877,6 +22283,7 @@ (define_insn "*prefetch_3dnow_rex"
     return "prefetchw\t%a0";
 }
   [(set_attr "type" "mmx")
+   (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
    (set_attr "memory" "none")])
 
 (define_expand "stack_protect_set"
@@ -22035,6 +22442,14 @@ (define_insn "sse4_2_crc32<mode>"
   [(set_attr "type" "sselog1")
    (set_attr "prefix_rep" "1")
    (set_attr "prefix_extra" "1")
+   (set (attr "prefix_data16")
+     (if_then_else (match_operand:HI 2 "" "")
+       (const_string "1")
+       (const_string "*")))
+   (set (attr "prefix_rex")
+     (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "SI")])
 
 (define_insn "sse4_2_crc32di"
--- gcc/output.h.jj	2009-01-14 12:06:29.000000000 +0100
+++ gcc/output.h	2009-06-09 10:46:09.000000000 +0200
@@ -1,7 +1,7 @@
 /* Declarations for insn-output.c.  These functions are defined in recog.c,
    final.c, and varasm.c.
    Copyright (C) 1987, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -94,6 +94,10 @@ extern int insn_current_reference_addres
    Defined in final.c.  */
 extern int label_to_alignment (rtx);
 
+/* Find the alignment maximum skip associated with a CODE_LABEL.
+   Defined in final.c.  */
+extern int label_to_max_skip (rtx);
+
 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */
 extern void output_asm_label (rtx);
 

gcc44-unwind-debug-hook.patch:

--- NEW FILE gcc44-unwind-debug-hook.patch ---
2009-05-27  Tom Tromey  <tromey at redhat.com>

	* unwind-dw2.c (_Unwind_DebugHook): New function.
	(uw_install_context): Call _Unwind_DebugHook.

--- gcc/unwind-dw2.c	(revision 147933)
+++ gcc/unwind-dw2.c	(revision 147934)
@@ -1473,18 +1473,31 @@ uw_init_context_1 (struct _Unwind_Contex
   context->ra = __builtin_extract_return_addr (outer_ra);
 }
 
+static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__));
+
+/* This function is called during unwinding.  It is intended as a hook
+   for a debugger to intercept exceptions.  CFA is the CFA of the
+   target frame.  HANDLER is the PC to which control will be
+   transferred.  */
+static void
+_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
+		   void *handler __attribute__ ((__unused__)))
+{
+  asm ("");
+}
 
 /* Install TARGET into CURRENT so that we can return to it.  This is a
    macro because __builtin_eh_return must be invoked in the context of
    our caller.  */
 
-#define uw_install_context(CURRENT, TARGET)				 \
-  do									 \
-    {									 \
-      long offset = uw_install_context_1 ((CURRENT), (TARGET));		 \
-      void *handler = __builtin_frob_return_addr ((TARGET)->ra);	 \
-      __builtin_eh_return (offset, handler);				 \
-    }									 \
+#define uw_install_context(CURRENT, TARGET)				\
+  do									\
+    {									\
+      long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
+      void *handler = __builtin_frob_return_addr ((TARGET)->ra);	\
+      _Unwind_DebugHook ((TARGET)->cfa, handler);			\
+      __builtin_eh_return (offset, handler);				\
+    }									\
   while (0)
 
 static long


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/gcc/devel/.cvsignore,v
retrieving revision 1.269
retrieving revision 1.270
diff -u -p -r1.269 -r1.270
--- .cvsignore	14 May 2009 08:52:30 -0000	1.269
+++ .cvsignore	9 Jun 2009 14:26:58 -0000	1.270
@@ -1,2 +1,2 @@
 fastjar-0.97.tar.gz
-gcc-4.4.0-20090514.tar.bz2
+gcc-4.4.0-20090609.tar.bz2


Index: gcc.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gcc/devel/gcc.spec,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -p -r1.42 -r1.43
--- gcc.spec	14 May 2009 08:52:30 -0000	1.42
+++ gcc.spec	9 Jun 2009 14:26:58 -0000	1.43
@@ -1,9 +1,9 @@
-%global DATE 20090514
-%global SVNREV 147523
+%global DATE 20090609
+%global SVNREV 148308
 %global gcc_version 4.4.0
 # Note, gcc_release must be integer, if you want to add suffixes to
 # %{release}, append them after %{gcc_release} on Release: line.
-%global gcc_release 5
+%global gcc_release 7
 %global _unpackaged_files_terminate_build 0
 %global multilib_64_archs sparc64 ppc64 s390x x86_64
 %global include_gappletviewer 1
@@ -157,9 +157,13 @@ Patch25: gcc44-power7.patch
 Patch26: gcc44-power7-2.patch
 Patch27: gcc44-power7-3.patch
 Patch28: gcc44-pr38757.patch
-Patch29: gcc44-pr39856.patch
-Patch30: gcc44-libstdc++-docs.patch
-Patch31: gcc44-pr39942.patch
+Patch29: gcc44-libstdc++-docs.patch
+Patch30: gcc44-atom-mnative.patch
+Patch31: gcc44-atom-movbe.patch
+Patch32: gcc44-ix86-insn-length.patch
+Patch33: gcc44-builtin-object-size.patch
+Patch34: gcc44-epilogue-unwind.patch
+Patch35: gcc44-unwind-debug-hook.patch
 
 Patch1000: fastjar-0.97-segfault.patch
 
@@ -464,11 +468,15 @@ which are required to compile with the G
 %patch26 -p0 -b .power7-2~
 %patch27 -p0 -b .power7-3~
 %patch28 -p0 -b .pr38757~
-%patch29 -p0 -b .pr39856~
 %if %{build_libstdcxx_docs}
-%patch30 -p0 -b .libstdc++-docs~
+%patch29 -p0 -b .libstdc++-docs~
 %endif
-%patch31 -p0 -b .pr39942~
+%patch30 -p0 -b .atom-mnative~
+%patch31 -p0 -b .atom-movbe~
+%patch32 -p0 -b .ix86-insn-length~
+%patch33 -p0 -b .builtin-object-size~
+%patch34 -p0 -b .epilogue-unwind~
+%patch35 -p0 -b .unwind-debug-hook~
 
 # This testcase doesn't compile.
 rm libjava/testsuite/libjava.lang/PR35020*
@@ -1803,6 +1811,29 @@ fi
 %doc rpm.doc/changelogs/libmudflap/ChangeLog*
 
 %changelog
+* Tue Jun  9 2009 Jakub Jelinek <jakub at redhat.com> 4.4.0-7
+- update from gcc-4_4-branch
+  - PRs ada/40166, bootstrap/40027, c++/38064, c++/39754, c++/40007,
+	c++/40139, c/40172, c++/40306, c++/40307, c++/40308, c++/40311,
+	c++/40370, c++/40372, c++/40373, debug/40109, fortran/22423,
+	fortran/38654, fortran/39893, fortran/40019, fortran/40195,
+	libfortran/25561, libfortran/37754, libfortran/38668,
+	libfortran/39665, libfortran/39667, libfortran/39702,
+	libfortran/39709, libfortran/39782, libfortran/40334,
+	libgfortran/39664, libgomp/40174, libstdc++/36211, libstdc++/40192,
+	libstdc++/40296, libstdc++/40299, middle-end/32950, middle-end/40147,
+	middle-end/40204, middle-end/40233, middle-end/40252,
+	middle-end/40291, middle-end/40328, middle-end/40340,
+	rtl-optimization/40105, target/40017, target/40153, target/40266,
+	testsuite/39907, tree-optimization/39999, tree-optimization/40087,
+	tree-optimization/40238, tree-optimization/40254
+- support Atom for -march=native
+- add -mmovbe support for Atom
+- improve ix86 instruction length computation, remove some unneeded padding
+- -D_FORTIFY_SOURCE improvements
+- emit accurate epilogue unwinding information
+- add unwind debug hook for gdb
+
 * Thu May 14 2009 Jakub Jelinek <jakub at redhat.com> 4.4.0-5
 - update from gcc-4_4-branch
   - PRs c++/17395, c/39983, fortran/38863, fortran/38956, fortran/39879,


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/gcc/devel/sources,v
retrieving revision 1.272
retrieving revision 1.273
diff -u -p -r1.272 -r1.273
--- sources	14 May 2009 08:52:31 -0000	1.272
+++ sources	9 Jun 2009 14:26:59 -0000	1.273
@@ -1,2 +1,2 @@
 2659f09c2e43ef8b7d4406321753f1b2  fastjar-0.97.tar.gz
-271340a1883a595c5c8b4fe1007389fa  gcc-4.4.0-20090514.tar.bz2
+aa85080477b7f1f5b6c526d2ad48bbf7  gcc-4.4.0-20090609.tar.bz2


--- gcc44-pr39856.patch DELETED ---


--- gcc44-pr39942.patch DELETED ---




More information about the fedora-extras-commits mailing list