changeset 1:cabe9c86a5b5

Moving some old patches to their own directory.
author Gregor Richards <Richards@codu.org>
date Fri, 24 Jul 2009 21:13:46 -0400
parents b10489e764e3
children 994ca5c4a51c
files diffs/binutils-2.17-winelf.diff diffs/binutils-2.18-winelf.diff diffs/gcc-3.4.5-20060117-1-winelf.diff diffs/gcc-4.1.2-winelf.diff diffs/gcc-4.2.3-winelf.diff diffs/gdc-0.23-winelf.diff diffs/gdc-0.24-winelf.diff diffs/old/binutils-2.17-winelf.diff diffs/old/binutils-2.18-winelf.diff diffs/old/gcc-3.4.5-20060117-1-winelf.diff diffs/old/gcc-4.1.2-winelf.diff diffs/old/gcc-4.2.3-winelf.diff diffs/old/gdc-0.23-winelf.diff diffs/old/gdc-0.24-winelf.diff
diffstat 14 files changed, 144813 insertions(+), 144813 deletions(-) [+]
line wrap: on
line diff
--- a/diffs/binutils-2.17-winelf.diff	Fri Jul 24 21:08:19 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-diff -ruN binutils-2.17/bfd/config.bfd binutils-2.17-winelf/bfd/config.bfd
---- binutils-2.17/bfd/config.bfd	2006-04-05 05:41:57.000000000 -0700
-+++ binutils-2.17-winelf/bfd/config.bfd	2007-03-09 10:59:13.000000000 -0800
-@@ -448,7 +448,8 @@
-     ;;
-   i[3-7]86-*-sysv4* | i[3-7]86-*-unixware* | \
-   i[3-7]86-*-elf | i[3-7]86-*-sco3.2v5* | \
--  i[3-7]86-*-dgux* | i[3-7]86-*-sysv5*)
-+  i[3-7]86-*-dgux* | i[3-7]86-*-sysv5* | \
-+  i[3-7]86-*-win32elf*)
-     targ_defvec=bfd_elf32_i386_vec
-     targ_selvecs=i386coff_vec
-     ;;
-diff -ruN binutils-2.17/config.sub binutils-2.17-winelf/config.sub
---- binutils-2.17/config.sub	2006-01-16 09:34:37.000000000 -0800
-+++ binutils-2.17-winelf/config.sub	2007-03-09 11:04:45.000000000 -0800
-@@ -1206,7 +1206,7 @@
- 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- 	      | -chorusos* | -chorusrdb* \
--	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* | -win32elf* \
- 	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- 	      | -uxpv* | -beos* | -mpeix* | -udk* \
- 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-diff -ruN binutils-2.17/gas/configure.tgt binutils-2.17-winelf/gas/configure.tgt
---- binutils-2.17/gas/configure.tgt	2006-04-05 05:41:57.000000000 -0700
-+++ binutils-2.17-winelf/gas/configure.tgt	2007-03-09 11:00:48.000000000 -0800
-@@ -210,6 +210,7 @@
-   i386-*-cygwin*)			fmt=coff em=pe ;;
-   i386-*-interix*)			fmt=coff em=interix ;;
-   i386-*-mingw32*)			fmt=coff em=pe ;;
-+  i386-*-win32elf*)			fmt=elf ;;
-   i386-*-nto-qnx*)			fmt=elf ;;
-   i386-*-*nt*)				fmt=coff em=pe ;;
-   i386-*-chaos)				fmt=elf ;;
-diff -ruN binutils-2.17/ld/configure.tgt binutils-2.17-winelf/ld/configure.tgt
---- binutils-2.17/ld/configure.tgt	2006-04-05 05:41:57.000000000 -0700
-+++ binutils-2.17-winelf/ld/configure.tgt	2007-03-09 11:16:10.000000000 -0800
-@@ -219,6 +219,7 @@
- 			targ_extra_ofiles="deffilep.o pe-dll.o" ;;
- i[3-7]86-*-interix*)	targ_emul=i386pe_posix;
-  			targ_extra_ofiles="deffilep.o pe-dll.o" ;;
-+i[3-7]86-*-win32elf*)   targ_emul=elf_i386 ;;
- i[3-7]86-*-beospe*)	targ_emul=i386beos ;;
- i[3-7]86-*-beos*)	targ_emul=elf_i386_be ;;
- i[3-7]86-*-vxworks*)	targ_emul=elf_i386_vxworks ;;
-diff -ruN binutils-2.17/libiberty/configure binutils-2.17-winelf/libiberty/configure
---- binutils-2.17/libiberty/configure	2006-04-06 17:01:25.000000000 -0700
-+++ binutils-2.17-winelf/libiberty/configure	2007-03-09 15:13:28.000000000 -0800
-@@ -5713,7 +5713,7 @@
- 
- 
- case "${host}" in
--  *-*-cygwin* | *-*-mingw*)
-+  *-*-cygwin* | *-*-mingw* | *-*-win32elf*)
-     cat >>confdefs.h <<\_ACEOF
- #define HAVE_SYS_ERRLIST 1
- _ACEOF
-@@ -5877,7 +5877,7 @@
-     fi
-     ;;
- 
--  *-*-mingw32*)
-+  *-*-mingw32* | *-*-win32elf*)
-     # Under mingw32, sys_nerr and sys_errlist exist, but they are
-     # macros, so the test below won't find them.
-     libiberty_cv_var_sys_nerr=yes
-@@ -8198,7 +8198,7 @@
- 
- # Figure out which version of pexecute to use.
- case "${host}" in
--     *-*-mingw* | *-*-winnt*)	pexecute=./pex-win32.o  ;;
-+     *-*-mingw* | *-*-winnt* | *-*-win32elf*)	pexecute=./pex-win32.o  ;;
-      *-*-msdosdjgpp*)		pexecute=./pex-djgpp.o  ;;
-      *-*-msdos*)		pexecute=./pex-msdos.o  ;;
-      *)				pexecute=./pex-unix.o   ;;
-diff -ruN binutils-2.17/libiberty/configure.ac binutils-2.17-winelf/libiberty/configure.ac
---- binutils-2.17/libiberty/configure.ac	2006-04-06 17:01:25.000000000 -0700
-+++ binutils-2.17-winelf/libiberty/configure.ac	2007-03-09 15:12:44.000000000 -0800
-@@ -451,7 +451,7 @@
- AC_SUBST(target_header_dir)
- 
- case "${host}" in
--  *-*-cygwin* | *-*-mingw*)
-+  *-*-cygwin* | *-*-mingw* | *-*-win32elf*)
-     AC_DEFINE(HAVE_SYS_ERRLIST)
-     AC_DEFINE(HAVE_SYS_NERR)
-     ;;
-@@ -526,7 +526,7 @@
-     fi
-     ;;
- 
--  *-*-mingw32*)
-+  *-*-mingw32* | *-*-win32elf*)
-     # Under mingw32, sys_nerr and sys_errlist exist, but they are
-     # macros, so the test below won't find them.
-     libiberty_cv_var_sys_nerr=yes
-@@ -611,7 +611,7 @@
- 
- # Figure out which version of pexecute to use.
- case "${host}" in
--     *-*-mingw* | *-*-winnt*)	pexecute=./pex-win32.o  ;;
-+     *-*-mingw* | *-*-winnt* | *-*-win32elf)	pexecute=./pex-win32.o  ;;
-      *-*-msdosdjgpp*)		pexecute=./pex-djgpp.o  ;;
-      *-*-msdos*)		pexecute=./pex-msdos.o  ;;
-      *)				pexecute=./pex-unix.o   ;;
--- a/diffs/binutils-2.18-winelf.diff	Fri Jul 24 21:08:19 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-diff -ruN binutils-2.18/bfd/config.bfd binutils-2.18-winelf/bfd/config.bfd
---- binutils-2.18/bfd/config.bfd	2007-08-28 10:19:33.000000000 -0700
-+++ binutils-2.18-winelf/bfd/config.bfd	2008-02-24 16:20:57.000000000 -0800
-@@ -478,7 +478,8 @@
-     ;;
-   i[3-7]86-*-sysv4* | i[3-7]86-*-unixware* | \
-   i[3-7]86-*-elf | i[3-7]86-*-sco3.2v5* | \
--  i[3-7]86-*-dgux* | i[3-7]86-*-sysv5*)
-+  i[3-7]86-*-dgux* | i[3-7]86-*-sysv5* | \
-+  i[3-7]86-*-win32elf*)
-     targ_defvec=bfd_elf32_i386_vec
-     targ_selvecs=i386coff_vec
-     ;;
-diff -ruN binutils-2.18/config.sub binutils-2.18-winelf/config.sub
---- binutils-2.18/config.sub	2007-08-06 13:00:30.000000000 -0700
-+++ binutils-2.18-winelf/config.sub	2008-02-24 16:20:57.000000000 -0800
-@@ -1217,7 +1217,7 @@
- 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- 	      | -chorusos* | -chorusrdb* \
--	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* | -win32elf* \
- 	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- 	      | -uxpv* | -beos* | -mpeix* | -udk* \
- 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
-diff -ruN binutils-2.18/gas/configure.tgt binutils-2.18-winelf/gas/configure.tgt
---- binutils-2.18/gas/configure.tgt	2007-08-28 10:19:36.000000000 -0700
-+++ binutils-2.18-winelf/gas/configure.tgt	2008-02-24 16:21:28.000000000 -0800
-@@ -221,6 +221,7 @@
-       x86_64*)				fmt=coff em=pep ;;
-       i*)				fmt=coff em=pe ;;
-     esac ;;
-+  i386-*-win32elf*)			fmt=elf ;;
-   i386-*-nto-qnx*)			fmt=elf ;;
-   i386-*-*nt*)				fmt=coff em=pe ;;
-   i386-*-chaos)				fmt=elf ;;
-diff -ruN binutils-2.18/ld/configure.tgt binutils-2.18-winelf/ld/configure.tgt
---- binutils-2.18/ld/configure.tgt	2007-08-28 10:19:42.000000000 -0700
-+++ binutils-2.18-winelf/ld/configure.tgt	2008-02-24 16:20:57.000000000 -0800
-@@ -267,6 +267,7 @@
- 			targ_extra_ofiles="deffilep.o pep-dll.o" ;;
- i[3-7]86-*-interix*)	targ_emul=i386pe_posix;
-  			targ_extra_ofiles="deffilep.o pe-dll.o" ;;
-+i[3-7]86-*-win32elf*)   targ_emul=elf_i386 ;;
- i[3-7]86-*-beospe*)	targ_emul=i386beos ;;
- i[3-7]86-*-beos*)	targ_emul=elf_i386_be ;;
- i[3-7]86-*-vxworks*)	targ_emul=elf_i386_vxworks ;;
-diff -ruN binutils-2.18/libiberty/configure binutils-2.18-winelf/libiberty/configure
---- binutils-2.18/libiberty/configure	2007-08-06 12:59:45.000000000 -0700
-+++ binutils-2.18-winelf/libiberty/configure	2008-02-24 16:20:57.000000000 -0800
-@@ -6012,7 +6012,7 @@
- 
- 
- case "${host}" in
--  *-*-cygwin* | *-*-mingw*)
-+  *-*-cygwin* | *-*-mingw* | *-*-win32elf*)
-     cat >>confdefs.h <<\_ACEOF
- #define HAVE_SYS_ERRLIST 1
- _ACEOF
-@@ -6196,7 +6196,7 @@
-     fi
-     ;;
- 
--  *-*-mingw32*)
-+  *-*-mingw32* | *-*-win32elf*)
-     # Under mingw32, sys_nerr and sys_errlist exist, but they are
-     # macros, so the test below won't find them.
-     libiberty_cv_var_sys_nerr=yes
-@@ -8517,7 +8517,7 @@
- 
- # Figure out which version of pexecute to use.
- case "${host}" in
--     *-*-mingw* | *-*-winnt*)	pexecute=./pex-win32.o  ;;
-+     *-*-mingw* | *-*-winnt* | *-*-win32elf*)	pexecute=./pex-win32.o  ;;
-      *-*-msdosdjgpp*)		pexecute=./pex-djgpp.o  ;;
-      *-*-msdos*)		pexecute=./pex-msdos.o  ;;
-      *)				pexecute=./pex-unix.o   ;;
-diff -ruN binutils-2.18/libiberty/configure.ac binutils-2.18-winelf/libiberty/configure.ac
---- binutils-2.18/libiberty/configure.ac	2007-08-06 12:59:45.000000000 -0700
-+++ binutils-2.18-winelf/libiberty/configure.ac	2008-02-24 16:20:57.000000000 -0800
-@@ -502,7 +502,7 @@
- AC_SUBST(target_header_dir)
- 
- case "${host}" in
--  *-*-cygwin* | *-*-mingw*)
-+  *-*-cygwin* | *-*-mingw* | *-*-win32elf*)
-     AC_DEFINE(HAVE_SYS_ERRLIST)
-     AC_DEFINE(HAVE_SYS_NERR)
-     ;;
-@@ -594,7 +594,7 @@
-     fi
-     ;;
- 
--  *-*-mingw32*)
-+  *-*-mingw32* | *-*-win32elf*)
-     # Under mingw32, sys_nerr and sys_errlist exist, but they are
-     # macros, so the test below won't find them.
-     libiberty_cv_var_sys_nerr=yes
-@@ -679,7 +679,7 @@
- 
- # Figure out which version of pexecute to use.
- case "${host}" in
--     *-*-mingw* | *-*-winnt*)	pexecute=./pex-win32.o  ;;
-+     *-*-mingw* | *-*-winnt* | *-*-win32elf)	pexecute=./pex-win32.o  ;;
-      *-*-msdosdjgpp*)		pexecute=./pex-djgpp.o  ;;
-      *-*-msdos*)		pexecute=./pex-msdos.o  ;;
-      *)				pexecute=./pex-unix.o   ;;
--- a/diffs/gcc-3.4.5-20060117-1-winelf.diff	Fri Jul 24 21:08:19 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131617 +0,0 @@
-diff -ruN gcc-3.4.5-20060117-1/config.sub gcc-3.4.5-20060117-1-winelf/config.sub
---- gcc-3.4.5-20060117-1/config.sub	2004-02-22 06:44:23.000000000 -0800
-+++ gcc-3.4.5-20060117-1-winelf/config.sub	2008-02-26 22:19:17.000000000 -0800
-@@ -1156,7 +1156,7 @@
- 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- 	      | -chorusos* | -chorusrdb* \
--	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* | -win32elf* \
- 	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
- 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-diff -ruN gcc-3.4.5-20060117-1/gcc/c-format.c.orig gcc-3.4.5-20060117-1-winelf/gcc/c-format.c.orig
---- gcc-3.4.5-20060117-1/gcc/c-format.c.orig	2005-05-01 03:39:15.000000000 -0700
-+++ gcc-3.4.5-20060117-1-winelf/gcc/c-format.c.orig	1969-12-31 16:00:00.000000000 -0800
-@@ -1,2817 +0,0 @@
--/* Check calls to formatted I/O functions (-Wformat).
--   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
--   2001, 2002, 2003 Free Software Foundation, Inc.
--
--This file is part of GCC.
--
--GCC is free software; you can redistribute it and/or modify it under
--the terms of the GNU General Public License as published by the Free
--Software Foundation; either version 2, or (at your option) any later
--version.
--
--GCC is distributed in the hope that it will be useful, but WITHOUT ANY
--WARRANTY; without even the implied warranty of MERCHANTABILITY or
--FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
--for more details.
--
--You should have received a copy of the GNU General Public License
--along with GCC; see the file COPYING.  If not, write to the Free
--Software Foundation, 59 Temple Place - Suite 330, Boston, MA
--02111-1307, USA.  */
--
--#include "config.h"
--#include "system.h"
--#include "coretypes.h"
--#include "tm.h"
--#include "tree.h"
--#include "flags.h"
--#include "toplev.h"
--#include "c-common.h"
--#include "intl.h"
--#include "diagnostic.h"
--#include "langhooks.h"
--
--/* Set format warning options according to a -Wformat=n option.  */
--
--void
--set_Wformat (int setting)
--{
--  warn_format = setting;
--  warn_format_extra_args = setting;
--  warn_format_zero_length = setting;
--  if (setting != 1)
--    {
--      warn_format_nonliteral = setting;
--      warn_format_security = setting;
--      warn_format_y2k = setting;
--    }
--  /* Make sure not to disable -Wnonnull if -Wformat=0 is specified.  */
--  if (setting)
--    warn_nonnull = setting;
--}
--
--
--/* Handle attributes associated with format checking.  */
--
--/* This must be in the same order as format_types, with format_type_error
--   last.  */
--enum format_type { printf_format_type, asm_fprintf_format_type,
--		   gcc_diag_format_type, gcc_cdiag_format_type,
--		   gcc_cxxdiag_format_type,
--		   scanf_format_type, strftime_format_type,
--		   strfmon_format_type, format_type_error };
--
--typedef struct function_format_info
--{
--  enum format_type format_type;	/* type of format (printf, scanf, etc.) */
--  unsigned HOST_WIDE_INT format_num;	/* number of format argument */
--  unsigned HOST_WIDE_INT first_arg_num;	/* number of first arg (zero for varargs) */
--} function_format_info;
--
--static bool decode_format_attr (tree, function_format_info *, int);
--static enum format_type decode_format_type (const char *);
--
--static bool check_format_string (tree argument,
--				 unsigned HOST_WIDE_INT format_num,
--				 int flags, bool *no_add_attrs);
--static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
--			  int validated_p);
--
--
--/* Handle a "format_arg" attribute; arguments as in
--   struct attribute_spec.handler.  */
--tree
--handle_format_arg_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
--			     tree args, int flags, bool *no_add_attrs)
--{
--  tree type = *node;
--  tree format_num_expr = TREE_VALUE (args);
--  unsigned HOST_WIDE_INT format_num;
--  tree argument;
--
--  if (!get_constant (format_num_expr, &format_num, 0))
--    {
--      error ("format string has invalid operand number");
--      *no_add_attrs = true;
--      return NULL_TREE;
--    }
--
--  argument = TYPE_ARG_TYPES (type);
--  if (argument)
--    {
--      if (!check_format_string (argument, format_num, flags, no_add_attrs))
--	return NULL_TREE;
--    }
--
--  if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
--      || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
--	  != char_type_node))
--    {
--      if (!(flags & (int) ATTR_FLAG_BUILT_IN))
--	error ("function does not return string type");
--      *no_add_attrs = true;
--      return NULL_TREE;
--    }
--
--  return NULL_TREE;
--}
--
--/* Verify that the format_num argument is actually a string, in case
--   the format attribute is in error.  */
--static bool
--check_format_string (tree argument, unsigned HOST_WIDE_INT format_num,
--		     int flags, bool *no_add_attrs)
--{
--  unsigned HOST_WIDE_INT i;
--
--  for (i = 1; i != format_num; i++)
--    {
--      if (argument == 0)
--	break;
--      argument = TREE_CHAIN (argument);
--    }
--
--  if (!argument
--      || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
--      || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
--	  != char_type_node))
--    {
--      if (!(flags & (int) ATTR_FLAG_BUILT_IN))
--	error ("format string arg not a string type");
--      *no_add_attrs = true;
--      return false;
--    }
--
--  return true;
--}
--
--/* Strip any conversions from the expression, verify it is a constant,
--   and store its value. If validated_p is true, abort on errors.
--   Returns true on success, false otherwise.  */
--static bool
--get_constant(tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
--{
--  while (TREE_CODE (expr) == NOP_EXPR
--	 || TREE_CODE (expr) == CONVERT_EXPR
--	 || TREE_CODE (expr) == NON_LVALUE_EXPR)
--    expr = TREE_OPERAND (expr, 0);
--
--  if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
--    {
--      if (validated_p)
--	abort ();
--      return false;
--    }
--
--  *value = TREE_INT_CST_LOW (expr);
--
--  return true;
--}
--
--/* Decode the arguments to a "format" attribute into a function_format_info
--   structure.  It is already known that the list is of the right length.
--   If VALIDATED_P is true, then these attributes have already been validated
--   and this function will abort if they are erroneous; if false, it
--   will give an error message.  Returns true if the attributes are
--   successfully decoded, false otherwise.  */
--
--static bool
--decode_format_attr (tree args, function_format_info *info, int validated_p)
--{
--  tree format_type_id = TREE_VALUE (args);
--  tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
--  tree first_arg_num_expr
--    = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
--
--  if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
--    {
--      if (validated_p)
--	abort ();
--      error ("unrecognized format specifier");
--      return false;
--    }
--  else
--    {
--      const char *p = IDENTIFIER_POINTER (format_type_id);
--
--      info->format_type = decode_format_type (p);
--
--      if (info->format_type == format_type_error)
--	{
--	  if (validated_p)
--	    abort ();
--	  warning ("`%s' is an unrecognized format function type", p);
--	  return false;
--	}
--    }
--
--  if (!get_constant (format_num_expr, &info->format_num, validated_p))
--    {
--      error ("format string has invalid operand number");
--      return false;
--    }
--
--  if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
--    {
--      error ("'...' has invalid operand number");
--      return false;
--    }
--
--  if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
--    {
--      if (validated_p)
--	abort ();
--      error ("format string arg follows the args to be formatted");
--      return false;
--    }
--
--  return true;
--}
--
--/* Check a call to a format function against a parameter list.  */
--
--/* The meaningfully distinct length modifiers for format checking recognized
--   by GCC.  */
--enum format_lengths
--{
--  FMT_LEN_none,
--  FMT_LEN_hh,
--  FMT_LEN_h,
--  FMT_LEN_l,
--  FMT_LEN_ll,
--  FMT_LEN_L,
--  FMT_LEN_z,
--  FMT_LEN_t,
--  FMT_LEN_j,
--  FMT_LEN_MAX
--};
--
--
--/* The standard versions in which various format features appeared.  */
--enum format_std_version
--{
--  STD_C89,
--  STD_C94,
--  STD_C9L, /* C99, but treat as C89 if -Wno-long-long.  */
--  STD_C99,
--  STD_EXT
--};
--
--/* The C standard version C++ is treated as equivalent to
--   or inheriting from, for the purpose of format features supported.  */
--#define CPLUSPLUS_STD_VER	STD_C94
--/* The C standard version we are checking formats against when pedantic.  */
--#define C_STD_VER		((int)(c_dialect_cxx ()			  \
--				 ? CPLUSPLUS_STD_VER			  \
--				 : (flag_isoc99				  \
--				    ? STD_C99				  \
--				    : (flag_isoc94 ? STD_C94 : STD_C89))))
--/* The name to give to the standard version we are warning about when
--   pedantic.  FEATURE_VER is the version in which the feature warned out
--   appeared, which is higher than C_STD_VER.  */
--#define C_STD_NAME(FEATURE_VER) (c_dialect_cxx ()		\
--				 ? "ISO C++"			\
--				 : ((FEATURE_VER) == STD_EXT	\
--				    ? "ISO C"			\
--				    : "ISO C90"))
--/* Adjust a C standard version, which may be STD_C9L, to account for
--   -Wno-long-long.  Returns other standard versions unchanged.  */
--#define ADJ_STD(VER)		((int)((VER) == STD_C9L			      \
--				       ? (warn_long_long ? STD_C99 : STD_C89) \
--				       : (VER)))
--
--/* Flags that may apply to a particular kind of format checked by GCC.  */
--enum
--{
--  /* This format converts arguments of types determined by the
--     format string.  */
--  FMT_FLAG_ARG_CONVERT = 1,
--  /* The scanf allocation 'a' kludge applies to this format kind.  */
--  FMT_FLAG_SCANF_A_KLUDGE = 2,
--  /* A % during parsing a specifier is allowed to be a modified % rather
--     that indicating the format is broken and we are out-of-sync.  */
--  FMT_FLAG_FANCY_PERCENT_OK = 4,
--  /* With $ operand numbers, it is OK to reference the same argument more
--     than once.  */
--  FMT_FLAG_DOLLAR_MULTIPLE = 8,
--  /* This format type uses $ operand numbers (strfmon doesn't).  */
--  FMT_FLAG_USE_DOLLAR = 16,
--  /* Zero width is bad in this type of format (scanf).  */
--  FMT_FLAG_ZERO_WIDTH_BAD = 32,
--  /* Empty precision specification is OK in this type of format (printf).  */
--  FMT_FLAG_EMPTY_PREC_OK = 64,
--  /* Gaps are allowed in the arguments with $ operand numbers if all
--     arguments are pointers (scanf).  */
--  FMT_FLAG_DOLLAR_GAP_POINTER_OK = 128
--  /* Not included here: details of whether width or precision may occur
--     (controlled by width_char and precision_char); details of whether
--     '*' can be used for these (width_type and precision_type); details
--     of whether length modifiers can occur (length_char_specs).  */
--};
--
--
--/* Structure describing a length modifier supported in format checking, and
--   possibly a doubled version such as "hh".  */
--typedef struct
--{
--  /* Name of the single-character length modifier.  */
--  const char *name;
--  /* Index into a format_char_info.types array.  */
--  enum format_lengths index;
--  /* Standard version this length appears in.  */
--  enum format_std_version std;
--  /* Same, if the modifier can be repeated, or NULL if it can't.  */
--  const char *double_name;
--  enum format_lengths double_index;
--  enum format_std_version double_std;
--} format_length_info;
--
--
--/* Structure describing the combination of a conversion specifier
--   (or a set of specifiers which act identically) and a length modifier.  */
--typedef struct
--{
--  /* The standard version this combination of length and type appeared in.
--     This is only relevant if greater than those for length and type
--     individually; otherwise it is ignored.  */
--  enum format_std_version std;
--  /* The name to use for the type, if different from that generated internally
--     (e.g., "signed size_t").  */
--  const char *name;
--  /* The type itself.  */
--  tree *type;
--} format_type_detail;
--
--
--/* Macros to fill out tables of these.  */
--#define NOARGUMENTS	{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }
--#define BADLEN	{ 0, NULL, NULL }
--#define NOLENGTHS	{ BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }
--
--
--/* Structure describing a format conversion specifier (or a set of specifiers
--   which act identically), and the length modifiers used with it.  */
--typedef struct
--{
--  const char *format_chars;
--  int pointer_count;
--  enum format_std_version std;
--  /* Types accepted for each length modifier.  */
--  format_type_detail types[FMT_LEN_MAX];
--  /* List of other modifier characters allowed with these specifiers.
--     This lists flags, and additionally "w" for width, "p" for precision
--     (right precision, for strfmon), "#" for left precision (strfmon),
--     "a" for scanf "a" allocation extension (not applicable in C99 mode),
--     "*" for scanf suppression, and "E" and "O" for those strftime
--     modifiers.  */
--  const char *flag_chars;
--  /* List of additional flags describing these conversion specifiers.
--     "c" for generic character pointers being allowed, "2" for strftime
--     two digit year formats, "3" for strftime formats giving two digit
--     years in some locales, "4" for "2" which becomes "3" with an "E" modifier,
--     "o" if use of strftime "O" is a GNU extension beyond C99,
--     "W" if the argument is a pointer which is dereferenced and written into,
--     "R" if the argument is a pointer which is dereferenced and read from,
--     "i" for printf integer formats where the '0' flag is ignored with
--     precision, and "[" for the starting character of a scanf scanset.  */
--  const char *flags2;
--} format_char_info;
--
--
--/* Structure describing a flag accepted by some kind of format.  */
--typedef struct
--{
--  /* The flag character in question (0 for end of array).  */
--  int flag_char;
--  /* Zero if this entry describes the flag character in general, or a
--     nonzero character that may be found in flags2 if it describes the
--     flag when used with certain formats only.  If the latter, only
--     the first such entry found that applies to the current conversion
--     specifier is used; the values of `name' and `long_name' it supplies
--     will be used, if non-NULL and the standard version is higher than
--     the unpredicated one, for any pedantic warning.  For example, 'o'
--     for strftime formats (meaning 'O' is an extension over C99).  */
--  int predicate;
--  /* Nonzero if the next character after this flag in the format should
--     be skipped ('=' in strfmon), zero otherwise.  */
--  int skip_next_char;
--  /* The name to use for this flag in diagnostic messages.  For example,
--     N_("`0' flag"), N_("field width").  */
--  const char *name;
--  /* Long name for this flag in diagnostic messages; currently only used for
--     "ISO C does not support ...".  For example, N_("the `I' printf flag").  */
--  const char *long_name;
--  /* The standard version in which it appeared.  */
--  enum format_std_version std;
--} format_flag_spec;
--
--
--/* Structure describing a combination of flags that is bad for some kind
--   of format.  */
--typedef struct
--{
--  /* The first flag character in question (0 for end of array).  */
--  int flag_char1;
--  /* The second flag character.  */
--  int flag_char2;
--  /* Nonzero if the message should say that the first flag is ignored with
--     the second, zero if the combination should simply be objected to.  */
--  int ignored;
--  /* Zero if this entry applies whenever this flag combination occurs,
--     a nonzero character from flags2 if it only applies in some
--     circumstances (e.g. 'i' for printf formats ignoring 0 with precision).  */
--  int predicate;
--} format_flag_pair;
--
--
--/* Structure describing a particular kind of format processed by GCC.  */
--typedef struct
--{
--  /* The name of this kind of format, for use in diagnostics.  Also
--     the name of the attribute (without preceding and following __).  */
--  const char *name;
--  /* Specifications of the length modifiers accepted; possibly NULL.  */
--  const format_length_info *length_char_specs;
--  /* Details of the conversion specification characters accepted.  */
--  const format_char_info *conversion_specs;
--  /* String listing the flag characters that are accepted.  */
--  const char *flag_chars;
--  /* String listing modifier characters (strftime) accepted.  May be NULL.  */
--  const char *modifier_chars;
--  /* Details of the flag characters, including pseudo-flags.  */
--  const format_flag_spec *flag_specs;
--  /* Details of bad combinations of flags.  */
--  const format_flag_pair *bad_flag_pairs;
--  /* Flags applicable to this kind of format.  */
--  int flags;
--  /* Flag character to treat a width as, or 0 if width not used.  */
--  int width_char;
--  /* Flag character to treat a left precision (strfmon) as,
--     or 0 if left precision not used.  */
--  int left_precision_char;
--  /* Flag character to treat a precision (for strfmon, right precision) as,
--     or 0 if precision not used.  */
--  int precision_char;
--  /* If a flag character has the effect of suppressing the conversion of
--     an argument ('*' in scanf), that flag character, otherwise 0.  */
--  int suppression_char;
--  /* Flag character to treat a length modifier as (ignored if length
--     modifiers not used).  Need not be placed in flag_chars for conversion
--     specifiers, but is used to check for bad combinations such as length
--     modifier with assignment suppression in scanf.  */
--  int length_code_char;
--  /* Pointer to type of argument expected if '*' is used for a width,
--     or NULL if '*' not used for widths.  */
--  tree *width_type;
--  /* Pointer to type of argument expected if '*' is used for a precision,
--     or NULL if '*' not used for precisions.  */
--  tree *precision_type;
--} format_kind_info;
--
--
--/* Structure describing details of a type expected in format checking,
--   and the type to check against it.  */
--typedef struct format_wanted_type
--{
--  /* The type wanted.  */
--  tree wanted_type;
--  /* The name of this type to use in diagnostics.  */
--  const char *wanted_type_name;
--  /* The level of indirection through pointers at which this type occurs.  */
--  int pointer_count;
--  /* Whether, when pointer_count is 1, to allow any character type when
--     pedantic, rather than just the character or void type specified.  */
--  int char_lenient_flag;
--  /* Whether the argument, dereferenced once, is written into and so the
--     argument must not be a pointer to a const-qualified type.  */
--  int writing_in_flag;
--  /* Whether the argument, dereferenced once, is read from and so
--     must not be a NULL pointer.  */
--  int reading_from_flag;
--  /* If warnings should be of the form "field precision is not type int",
--     the name to use (in this case "field precision"), otherwise NULL,
--     for "%s format, %s arg" type messages.  If (in an extension), this
--     is a pointer type, wanted_type_name should be set to include the
--     terminating '*' characters of the type name to give a correct
--     message.  */
--  const char *name;
--  /* The actual parameter to check against the wanted type.  */
--  tree param;
--  /* The argument number of that parameter.  */
--  int arg_num;
--  /* The next type to check for this format conversion, or NULL if none.  */
--  struct format_wanted_type *next;
--} format_wanted_type;
--
--
--static const format_length_info printf_length_specs[] =
--{
--  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
--  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
--  { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
--  { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
--  { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
--  { "Z", FMT_LEN_z, STD_EXT, NULL, 0, 0 },
--  { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
--  { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
--  { NULL, 0, 0, NULL, 0, 0 }
--};
--
--/* Length specifiers valid for asm_fprintf.  */
--static const format_length_info asm_fprintf_length_specs[] =
--{
--  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
--  { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
--  { NULL, 0, 0, NULL, 0, 0 }
--};
--
--/* Length specifiers valid for GCC diagnostics.  */
--static const format_length_info gcc_diag_length_specs[] =
--{
--  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
--  { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
--  { NULL, 0, 0, NULL, 0, 0 }
--};
--
--/* The custom diagnostics all accept the same length specifiers.  */
--#define gcc_cdiag_length_specs gcc_diag_length_specs
--#define gcc_cxxdiag_length_specs gcc_diag_length_specs
--
--/* This differs from printf_length_specs only in that "Z" is not accepted.  */
--static const format_length_info scanf_length_specs[] =
--{
--  { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
--  { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
--  { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
--  { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
--  { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
--  { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
--  { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
--  { NULL, 0, 0, NULL, 0, 0 }
--};
--
--
--/* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
--   make no sense for a format type not part of any C standard version.  */
--static const format_length_info strfmon_length_specs[] =
--{
--  /* A GNU extension.  */
--  { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
--  { NULL, 0, 0, NULL, 0, 0 }
--};
--
--static const format_flag_spec printf_flag_specs[] =
--{
--  { ' ',  0, 0, N_("` ' flag"),        N_("the ` ' printf flag"),              STD_C89 },
--  { '+',  0, 0, N_("`+' flag"),        N_("the `+' printf flag"),              STD_C89 },
--  { '#',  0, 0, N_("`#' flag"),        N_("the `#' printf flag"),              STD_C89 },
--  { '0',  0, 0, N_("`0' flag"),        N_("the `0' printf flag"),              STD_C89 },
--  { '-',  0, 0, N_("`-' flag"),        N_("the `-' printf flag"),              STD_C89 },
--  { '\'', 0, 0, N_("`'' flag"),        N_("the `'' printf flag"),              STD_EXT },
--  { 'I',  0, 0, N_("`I' flag"),        N_("the `I' printf flag"),              STD_EXT },
--  { 'w',  0, 0, N_("field width"),     N_("field width in printf format"),     STD_C89 },
--  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
--  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
--  { 0, 0, 0, NULL, NULL, 0 }
--};
--
--
--static const format_flag_pair printf_flag_pairs[] =
--{
--  { ' ', '+', 1, 0   },
--  { '0', '-', 1, 0   },
--  { '0', 'p', 1, 'i' },
--  { 0, 0, 0, 0 }
--};
--
--static const format_flag_spec asm_fprintf_flag_specs[] =
--{
--  { ' ',  0, 0, N_("` ' flag"),        N_("the ` ' printf flag"),              STD_C89 },
--  { '+',  0, 0, N_("`+' flag"),        N_("the `+' printf flag"),              STD_C89 },
--  { '#',  0, 0, N_("`#' flag"),        N_("the `#' printf flag"),              STD_C89 },
--  { '0',  0, 0, N_("`0' flag"),        N_("the `0' printf flag"),              STD_C89 },
--  { '-',  0, 0, N_("`-' flag"),        N_("the `-' printf flag"),              STD_C89 },
--  { 'w',  0, 0, N_("field width"),     N_("field width in printf format"),     STD_C89 },
--  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
--  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
--  { 0, 0, 0, NULL, NULL, 0 }
--};
--
--static const format_flag_pair asm_fprintf_flag_pairs[] =
--{
--  { ' ', '+', 1, 0   },
--  { '0', '-', 1, 0   },
--  { '0', 'p', 1, 'i' },
--  { 0, 0, 0, 0 }
--};
--
--static const format_flag_pair gcc_diag_flag_pairs[] =
--{
--  { 0, 0, 0, 0 }
--};
--
--#define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
--#define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
--
--static const format_flag_spec gcc_diag_flag_specs[] =
--{
--  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
--  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
--  { 0, 0, 0, NULL, NULL, 0 }
--};
--
--#define gcc_cdiag_flag_specs gcc_diag_flag_specs
--
--static const format_flag_spec gcc_cxxdiag_flag_specs[] =
--{
--  { '+',  0, 0, N_("`+' flag"),        N_("the `+' printf flag"),              STD_C89 },
--  { '#',  0, 0, N_("`#' flag"),        N_("the `#' printf flag"),              STD_C89 },
--  { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
--  { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
--  { 0, 0, 0, NULL, NULL, 0 }
--};
--
--static const format_flag_spec scanf_flag_specs[] =
--{
--  { '*',  0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
--  { 'a',  0, 0, N_("`a' flag"),               N_("the `a' scanf flag"),                       STD_EXT },
--  { 'w',  0, 0, N_("field width"),            N_("field width in scanf format"),              STD_C89 },
--  { 'L',  0, 0, N_("length modifier"),        N_("length modifier in scanf format"),          STD_C89 },
--  { '\'', 0, 0, N_("`'' flag"),               N_("the `'' scanf flag"),                       STD_EXT },
--  { 'I',  0, 0, N_("`I' flag"),               N_("the `I' scanf flag"),                       STD_EXT },
--  { 0, 0, 0, NULL, NULL, 0 }
--};
--
--
--static const format_flag_pair scanf_flag_pairs[] =
--{
--  { '*', 'L', 0, 0 },
--  { 0, 0, 0, 0 }
--};
--
--
--static const format_flag_spec strftime_flag_specs[] =
--{
--  { '_', 0,   0, N_("`_' flag"),     N_("the `_' strftime flag"),          STD_EXT },
--  { '-', 0,   0, N_("`-' flag"),     N_("the `-' strftime flag"),          STD_EXT },
--  { '0', 0,   0, N_("`0' flag"),     N_("the `0' strftime flag"),          STD_EXT },
--  { '^', 0,   0, N_("`^' flag"),     N_("the `^' strftime flag"),          STD_EXT },
--  { '#', 0,   0, N_("`#' flag"),     N_("the `#' strftime flag"),          STD_EXT },
--  { 'w', 0,   0, N_("field width"),  N_("field width in strftime format"), STD_EXT },
--  { 'E', 0,   0, N_("`E' modifier"), N_("the `E' strftime modifier"),      STD_C99 },
--  { 'O', 0,   0, N_("`O' modifier"), N_("the `O' strftime modifier"),      STD_C99 },
--  { 'O', 'o', 0, NULL,               N_("the `O' modifier"),               STD_EXT },
--  { 0, 0, 0, NULL, NULL, 0 }
--};
--
--
--static const format_flag_pair strftime_flag_pairs[] =
--{
--  { 'E', 'O', 0, 0 },
--  { '_', '-', 0, 0 },
--  { '_', '0', 0, 0 },
--  { '-', '0', 0, 0 },
--  { '^', '#', 0, 0 },
--  { 0, 0, 0, 0 }
--};
--
--
--static const format_flag_spec strfmon_flag_specs[] =
--{
--  { '=',  0, 1, N_("fill character"),  N_("fill character in strfmon format"),  STD_C89 },
--  { '^',  0, 0, N_("`^' flag"),        N_("the `^' strfmon flag"),              STD_C89 },
--  { '+',  0, 0, N_("`+' flag"),        N_("the `+' strfmon flag"),              STD_C89 },
--  { '(',  0, 0, N_("`(' flag"),        N_("the `(' strfmon flag"),              STD_C89 },
--  { '!',  0, 0, N_("`!' flag"),        N_("the `!' strfmon flag"),              STD_C89 },
--  { '-',  0, 0, N_("`-' flag"),        N_("the `-' strfmon flag"),              STD_C89 },
--  { 'w',  0, 0, N_("field width"),     N_("field width in strfmon format"),     STD_C89 },
--  { '#',  0, 0, N_("left precision"),  N_("left precision in strfmon format"),  STD_C89 },
--  { 'p',  0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
--  { 'L',  0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
--  { 0, 0, 0, NULL, NULL, 0 }
--};
--
--static const format_flag_pair strfmon_flag_pairs[] =
--{
--  { '+', '(', 0, 0 },
--  { 0, 0, 0, 0 }
--};
--
--
--#define T_I	&integer_type_node
--#define T89_I	{ STD_C89, NULL, T_I }
--#define T_L	&long_integer_type_node
--#define T89_L	{ STD_C89, NULL, T_L }
--#define T_LL	&long_long_integer_type_node
--#define T9L_LL	{ STD_C9L, NULL, T_LL }
--#define TEX_LL	{ STD_EXT, NULL, T_LL }
--#define T_S	&short_integer_type_node
--#define T89_S	{ STD_C89, NULL, T_S }
--#define T_UI	&unsigned_type_node
--#define T89_UI	{ STD_C89, NULL, T_UI }
--#define T_UL	&long_unsigned_type_node
--#define T89_UL	{ STD_C89, NULL, T_UL }
--#define T_ULL	&long_long_unsigned_type_node
--#define T9L_ULL	{ STD_C9L, NULL, T_ULL }
--#define TEX_ULL	{ STD_EXT, NULL, T_ULL }
--#define T_US	&short_unsigned_type_node
--#define T89_US	{ STD_C89, NULL, T_US }
--#define T_F	&float_type_node
--#define T89_F	{ STD_C89, NULL, T_F }
--#define T99_F	{ STD_C99, NULL, T_F }
--#define T_D	&double_type_node
--#define T89_D	{ STD_C89, NULL, T_D }
--#define T99_D	{ STD_C99, NULL, T_D }
--#define T_LD	&long_double_type_node
--#define T89_LD	{ STD_C89, NULL, T_LD }
--#define T99_LD	{ STD_C99, NULL, T_LD }
--#define T_C	&char_type_node
--#define T89_C	{ STD_C89, NULL, T_C }
--#define T_SC	&signed_char_type_node
--#define T99_SC	{ STD_C99, NULL, T_SC }
--#define T_UC	&unsigned_char_type_node
--#define T99_UC	{ STD_C99, NULL, T_UC }
--#define T_V	&void_type_node
--#define T89_V	{ STD_C89, NULL, T_V }
--#define T_W	&wchar_type_node
--#define T94_W	{ STD_C94, "wchar_t", T_W }
--#define TEX_W	{ STD_EXT, "wchar_t", T_W }
--#define T_WI	&wint_type_node
--#define T94_WI	{ STD_C94, "wint_t", T_WI }
--#define TEX_WI	{ STD_EXT, "wint_t", T_WI }
--#define T_ST    &size_type_node
--#define T99_ST	{ STD_C99, "size_t", T_ST }
--#define T_SST   &signed_size_type_node
--#define T99_SST	{ STD_C99, "signed size_t", T_SST }
--#define T_PD    &ptrdiff_type_node
--#define T99_PD	{ STD_C99, "ptrdiff_t", T_PD }
--#define T_UPD   &unsigned_ptrdiff_type_node
--#define T99_UPD	{ STD_C99, "unsigned ptrdiff_t", T_UPD }
--#define T_IM    &intmax_type_node
--#define T99_IM	{ STD_C99, "intmax_t", T_IM }
--#define T_UIM   &uintmax_type_node
--#define T99_UIM	{ STD_C99, "uintmax_t", T_UIM }
--
--static const format_char_info print_char_table[] =
--{
--  /* C89 conversion specifiers.  */
--  { "di",  0, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  TEX_LL,  T99_SST, T99_PD,  T99_IM  }, "-wp0 +'I",  "i"  },
--  { "oxX", 0, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "-wp0#",     "i"  },
--  { "u",   0, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "-wp0'I",    "i"  },
--  { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'I", ""   },
--  { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#I",  ""   },
--  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T94_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        ""   },
--  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       "cR" },
--  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        "c"  },
--  { "n",   1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",          "W"  },
--  /* C99 conversion specifiers.  */
--  { "F",   0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'I", ""   },
--  { "aA",  0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#",   ""   },
--  /* X/Open conversion specifiers.  */
--  { "C",   0, STD_EXT, { TEX_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        ""   },
--  { "S",   1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       "R"  },
--  /* GNU conversion specifiers.  */
--  { "m",   0, STD_EXT, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       ""   },
--  { NULL,  0, 0, NOLENGTHS, NULL, NULL }
--};
--
--static const format_char_info asm_fprintf_char_table[] =
--{
--  /* C89 conversion specifiers.  */
--  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +",  "i" },
--  { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0#",   "i" },
--  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0",    "i" },
--  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",       "" },
--  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",    "cR" },
--
--  /* asm_fprintf conversion specifiers.  */
--  { "O",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { "R",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { "I",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { "L",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { "U",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { "r",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  "" },
--  { "@",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { NULL,  0, 0, NOLENGTHS, NULL, NULL }
--};
--
--static const format_char_info gcc_diag_char_table[] =
--{
--  /* C89 conversion specifiers.  */
--  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "p",  "cR" },
--  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "c"  },
--
--  /* Custom conversion specifiers.  */
--
--  /* %H will require "location_t" at runtime.  */
--  { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--
--  /* These will require a "tree" at runtime.  */
--  { "J", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--
--  { "m",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { NULL,  0, 0, NOLENGTHS, NULL, NULL }
--};
--
--static const format_char_info gcc_cdiag_char_table[] =
--{
--  /* C89 conversion specifiers.  */
--  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "p",  "cR" },
--  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "c"  },
--
--  /* Custom conversion specifiers.  */
--
--  /* %H will require "location_t" at runtime.  */
--  { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--
--  /* These will require a "tree" at runtime.  */
--  { "DEFJT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--
--  { "m",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { NULL,  0, 0, NOLENGTHS, NULL, NULL }
--};
--
--static const format_char_info gcc_cxxdiag_char_table[] =
--{
--  /* C89 conversion specifiers.  */
--  { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  ""   },
--  { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--  { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "p",  "cR" },
--  { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "c"  },
--
--  /* Custom conversion specifiers.  */
--
--  /* %H will require "location_t" at runtime.  */
--  { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--
--  /* These will require a "tree" at runtime.  */
--  { "ADEFJTV",0,STD_C89,{ T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "+#",   ""   },
--
--  /* These accept either an `int' or an `enum tree_code' (which is handled as an `int'.)  */
--  { "CLOPQ",0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   ""   },
--
--  { "m",   0, STD_C89, NOARGUMENTS, "",      ""   },
--  { NULL,  0, 0, NOLENGTHS, NULL, NULL }
--};
--
--static const format_char_info scan_char_table[] =
--{
--  /* C89 conversion specifiers.  */
--  { "di",    1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  TEX_LL,  T99_SST, T99_PD,  T99_IM  }, "*w'I", "W"   },
--  { "u",     1, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "*w'I", "W"   },
--  { "oxX",   1, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "*w",   "W"   },
--  { "efgEG", 1, STD_C89, { T89_F,   BADLEN,  BADLEN,  T89_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W"   },
--  { "c",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "cW"  },
--  { "s",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW"  },
--  { "[",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW[" },
--  { "p",     2, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W"   },
--  { "n",     1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",     "W"   },
--  /* C99 conversion specifiers.  */
--  { "FaA",   1, STD_C99, { T99_F,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W"   },
--  /* X/Open conversion specifiers.  */
--  { "C",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W"   },
--  { "S",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "W"   },
--  { NULL, 0, 0, NOLENGTHS, NULL, NULL }
--};
--
--static const format_char_info time_char_table[] =
--{
--  /* C89 conversion specifiers.  */
--  { "ABZab",		0, STD_C89, NOLENGTHS, "^#",     ""   },
--  { "cx", 		0, STD_C89, NOLENGTHS, "E",      "3"  },
--  { "HIMSUWdmw",	0, STD_C89, NOLENGTHS, "-_0Ow",  ""   },
--  { "j",		0, STD_C89, NOLENGTHS, "-_0Ow",  "o"  },
--  { "p",		0, STD_C89, NOLENGTHS, "#",      ""   },
--  { "X",		0, STD_C89, NOLENGTHS, "E",      ""   },
--  { "y", 		0, STD_C89, NOLENGTHS, "EO-_0w", "4"  },
--  { "Y",		0, STD_C89, NOLENGTHS, "-_0EOw", "o"  },
--  { "%",		0, STD_C89, NOLENGTHS, "",       ""   },
--  /* C99 conversion specifiers.  */
--  { "C",		0, STD_C99, NOLENGTHS, "-_0EOw", "o"  },
--  { "D", 		0, STD_C99, NOLENGTHS, "",       "2"  },
--  { "eVu",		0, STD_C99, NOLENGTHS, "-_0Ow",  ""   },
--  { "FRTnrt",		0, STD_C99, NOLENGTHS, "",       ""   },
--  { "g", 		0, STD_C99, NOLENGTHS, "O-_0w",  "2o" },
--  { "G",		0, STD_C99, NOLENGTHS, "-_0Ow",  "o"  },
--  { "h",		0, STD_C99, NOLENGTHS, "^#",     ""   },
--  { "z",		0, STD_C99, NOLENGTHS, "O",      "o"  },
--  /* GNU conversion specifiers.  */
--  { "kls",		0, STD_EXT, NOLENGTHS, "-_0Ow",  ""   },
--  { "P",		0, STD_EXT, NOLENGTHS, "",       ""   },
--  { NULL,		0, 0, NOLENGTHS, NULL, NULL }
--};
--
--static const format_char_info monetary_char_table[] =
--{
--  { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "" },
--  { NULL, 0, 0, NOLENGTHS, NULL, NULL }
--};
--
--
--/* This must be in the same order as enum format_type.  */
--static const format_kind_info format_types_orig[] =
--{
--  { "printf",   printf_length_specs,  print_char_table, " +#0-'I", NULL, 
--    printf_flag_specs, printf_flag_pairs,
--    FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
--    'w', 0, 'p', 0, 'L',
--    &integer_type_node, &integer_type_node
--  },
--  { "asm_fprintf",   asm_fprintf_length_specs,  asm_fprintf_char_table, " +#0-", NULL, 
--    asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
--    FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
--    'w', 0, 'p', 0, 'L',
--    NULL, NULL
--  },
--  { "gcc_diag",   gcc_diag_length_specs,  gcc_diag_char_table, "", NULL, 
--    gcc_diag_flag_specs, gcc_diag_flag_pairs,
--    FMT_FLAG_ARG_CONVERT,
--    0, 0, 'p', 0, 'L',
--    NULL, &integer_type_node
--  },
--  { "gcc_cdiag",   gcc_cdiag_length_specs,  gcc_cdiag_char_table, "", NULL, 
--    gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
--    FMT_FLAG_ARG_CONVERT,
--    0, 0, 'p', 0, 'L',
--    NULL, &integer_type_node
--  },
--  { "gcc_cxxdiag",   gcc_cxxdiag_length_specs,  gcc_cxxdiag_char_table, "+#", NULL, 
--    gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
--    FMT_FLAG_ARG_CONVERT,
--    0, 0, 'p', 0, 'L',
--    NULL, &integer_type_node
--  },
--  { "scanf",    scanf_length_specs,   scan_char_table,  "*'I", NULL, 
--    scanf_flag_specs, scanf_flag_pairs,
--    FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
--    'w', 0, 0, '*', 'L',
--    NULL, NULL
--  },
--  { "strftime", NULL,                 time_char_table,  "_-0^#", "EO",
--    strftime_flag_specs, strftime_flag_pairs,
--    FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0,
--    NULL, NULL
--  },
--  { "strfmon",  strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, 
--    strfmon_flag_specs, strfmon_flag_pairs,
--    FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L',
--    NULL, NULL
--  }
--};
--
--/* This layer of indirection allows GCC to reassign format_types with
--   new data if necessary, while still allowing the original data to be
--   const.  */
--static const format_kind_info *format_types = format_types_orig;
--/* We can modify this one.  */
--static format_kind_info *dynamic_format_types;
--
--/* Structure detailing the results of checking a format function call
--   where the format expression may be a conditional expression with
--   many leaves resulting from nested conditional expressions.  */
--typedef struct
--{
--  /* Number of leaves of the format argument that could not be checked
--     as they were not string literals.  */
--  int number_non_literal;
--  /* Number of leaves of the format argument that were null pointers or
--     string literals, but had extra format arguments.  */
--  int number_extra_args;
--  /* Number of leaves of the format argument that were null pointers or
--     string literals, but had extra format arguments and used $ operand
--     numbers.  */
--  int number_dollar_extra_args;
--  /* Number of leaves of the format argument that were wide string
--     literals.  */
--  int number_wide;
--  /* Number of leaves of the format argument that were empty strings.  */
--  int number_empty;
--  /* Number of leaves of the format argument that were unterminated
--     strings.  */
--  int number_unterminated;
--  /* Number of leaves of the format argument that were not counted above.  */
--  int number_other;
--} format_check_results;
--
--typedef struct
--{
--  format_check_results *res;
--  function_format_info *info;
--  tree params;
--  int *status;
--} format_check_context;
--
--static void check_format_info (int *, function_format_info *, tree);
--static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
--static void check_format_info_main (int *, format_check_results *,
--				    function_format_info *,
--				    const char *, int, tree,
--				    unsigned HOST_WIDE_INT);
--static void status_warning (int *, const char *, ...)
--     ATTRIBUTE_PRINTF_2;
--
--static void init_dollar_format_checking (int, tree);
--static int maybe_read_dollar_number (int *, const char **, int,
--				     tree, tree *, const format_kind_info *);
--static void finish_dollar_format_checking (int *, format_check_results *, int);
--
--static const format_flag_spec *get_flag_spec (const format_flag_spec *,
--					      int, const char *);
--
--static void check_format_types (int *, format_wanted_type *);
--
--/* Decode a format type from a string, returning the type, or
--   format_type_error if not valid, in which case the caller should print an
--   error message.  */
--static enum format_type
--decode_format_type (const char *s)
--{
--  int i;
--  int slen;
--  slen = strlen (s);
--  for (i = 0; i < (int) format_type_error; i++)
--    {
--      int alen;
--      if (!strcmp (s, format_types[i].name))
--	break;
--      alen = strlen (format_types[i].name);
--      if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
--	  && s[slen - 1] == '_' && s[slen - 2] == '_'
--	  && !strncmp (s + 2, format_types[i].name, alen))
--	break;
--    }
--  return ((enum format_type) i);
--}
--
--
--/* Check the argument list of a call to printf, scanf, etc.
--   ATTRS are the attributes on the function type.
--   PARAMS is the list of argument values.  Also, if -Wmissing-format-attribute,
--   warn for calls to vprintf or vscanf in functions with no such format
--   attribute themselves.  */
--
--void
--check_function_format (int *status, tree attrs, tree params)
--{
--  tree a;
--
--  /* See if this function has any format attributes.  */
--  for (a = attrs; a; a = TREE_CHAIN (a))
--    {
--      if (is_attribute_p ("format", TREE_PURPOSE (a)))
--	{
--	  /* Yup; check it.  */
--	  function_format_info info;
--	  decode_format_attr (TREE_VALUE (a), &info, 1);
--	  check_format_info (status, &info, params);
--	  if (warn_missing_format_attribute && info.first_arg_num == 0
--	      && (format_types[info.format_type].flags
--		  & (int) FMT_FLAG_ARG_CONVERT))
--	    {
--	      tree c;
--	      for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
--		   c;
--		   c = TREE_CHAIN (c))
--		if (is_attribute_p ("format", TREE_PURPOSE (c))
--		    && (decode_format_type (IDENTIFIER_POINTER
--					    (TREE_VALUE (TREE_VALUE (c))))
--			== info.format_type))
--		  break;
--	      if (c == NULL_TREE)
--		{
--		  /* Check if the current function has a parameter to which
--		     the format attribute could be attached; if not, it
--		     can't be a candidate for a format attribute, despite
--		     the vprintf-like or vscanf-like call.  */
--		  tree args;
--		  for (args = DECL_ARGUMENTS (current_function_decl);
--		       args != 0;
--		       args = TREE_CHAIN (args))
--		    {
--		      if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
--			  && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
--			      == char_type_node))
--			break;
--		    }
--		  if (args != 0)
--		    warning ("function might be possible candidate for `%s' format attribute",
--			     format_types[info.format_type].name);
--		}
--	    }
--	}
--    }
--}
--
--/* This function replaces `warning' inside the printf format checking
--   functions.  If the `status' parameter is non-NULL, then it is
--   dereferenced and set to 1 whenever a warning is caught.  Otherwise
--   it warns as usual by replicating the innards of the warning
--   function from diagnostic.c.  */
--static void
--status_warning (int *status, const char *msgid, ...)
--{
--  diagnostic_info diagnostic ;
--  va_list ap;
--  
--  va_start (ap, msgid);
--
--  if (status)
--    *status = 1;
--  else
--    {
--      /* This duplicates the warning function behavior.  */
--      diagnostic_set_info (&diagnostic, _(msgid), &ap,
--			   input_location, DK_WARNING);
--      report_diagnostic (&diagnostic);
--    }
--
--  va_end (ap);
--}
--
--/* Variables used by the checking of $ operand number formats.  */
--static char *dollar_arguments_used = NULL;
--static char *dollar_arguments_pointer_p = NULL;
--static int dollar_arguments_alloc = 0;
--static int dollar_arguments_count;
--static int dollar_first_arg_num;
--static int dollar_max_arg_used;
--static int dollar_format_warned;
--
--/* Initialize the checking for a format string that may contain $
--   parameter number specifications; we will need to keep track of whether
--   each parameter has been used.  FIRST_ARG_NUM is the number of the first
--   argument that is a parameter to the format, or 0 for a vprintf-style
--   function; PARAMS is the list of arguments starting at this argument.  */
--
--static void
--init_dollar_format_checking (int first_arg_num, tree params)
--{
--  tree oparams = params;
--
--  dollar_first_arg_num = first_arg_num;
--  dollar_arguments_count = 0;
--  dollar_max_arg_used = 0;
--  dollar_format_warned = 0;
--  if (first_arg_num > 0)
--    {
--      while (params)
--	{
--	  dollar_arguments_count++;
--	  params = TREE_CHAIN (params);
--	}
--    }
--  if (dollar_arguments_alloc < dollar_arguments_count)
--    {
--      if (dollar_arguments_used)
--	free (dollar_arguments_used);
--      if (dollar_arguments_pointer_p)
--	free (dollar_arguments_pointer_p);
--      dollar_arguments_alloc = dollar_arguments_count;
--      dollar_arguments_used = xmalloc (dollar_arguments_alloc);
--      dollar_arguments_pointer_p = xmalloc (dollar_arguments_alloc);
--    }
--  if (dollar_arguments_alloc)
--    {
--      memset (dollar_arguments_used, 0, dollar_arguments_alloc);
--      if (first_arg_num > 0)
--	{
--	  int i = 0;
--	  params = oparams;
--	  while (params)
--	    {
--	      dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
--					       == POINTER_TYPE);
--	      params = TREE_CHAIN (params);
--	      i++;
--	    }
--	}
--    }
--}
--
--
--/* Look for a decimal number followed by a $ in *FORMAT.  If DOLLAR_NEEDED
--   is set, it is an error if one is not found; otherwise, it is OK.  If
--   such a number is found, check whether it is within range and mark that
--   numbered operand as being used for later checking.  Returns the operand
--   number if found and within range, zero if no such number was found and
--   this is OK, or -1 on error.  PARAMS points to the first operand of the
--   format; PARAM_PTR is made to point to the parameter referred to.  If
--   a $ format is found, *FORMAT is updated to point just after it.  */
--
--static int
--maybe_read_dollar_number (int *status, const char **format,
--			  int dollar_needed, tree params, tree *param_ptr,
--			  const format_kind_info *fki)
--{
--  int argnum;
--  int overflow_flag;
--  const char *fcp = *format;
--  if (! ISDIGIT (*fcp))
--    {
--      if (dollar_needed)
--	{
--	  status_warning (status, "missing $ operand number in format");
--	  return -1;
--	}
--      else
--	return 0;
--    }
--  argnum = 0;
--  overflow_flag = 0;
--  while (ISDIGIT (*fcp))
--    {
--      int nargnum;
--      nargnum = 10 * argnum + (*fcp - '0');
--      if (nargnum < 0 || nargnum / 10 != argnum)
--	overflow_flag = 1;
--      argnum = nargnum;
--      fcp++;
--    }
--  if (*fcp != '$')
--    {
--      if (dollar_needed)
--	{
--	  status_warning (status, "missing $ operand number in format");
--	  return -1;
--	}
--      else
--	return 0;
--    }
--  *format = fcp + 1;
--  if (pedantic && !dollar_format_warned)
--    {
--      status_warning (status,
--		      "%s does not support %%n$ operand number formats",
--		      C_STD_NAME (STD_EXT));
--      dollar_format_warned = 1;
--    }
--  if (overflow_flag || argnum == 0
--      || (dollar_first_arg_num && argnum > dollar_arguments_count))
--    {
--      status_warning (status, "operand number out of range in format");
--      return -1;
--    }
--  if (argnum > dollar_max_arg_used)
--    dollar_max_arg_used = argnum;
--  /* For vprintf-style functions we may need to allocate more memory to
--     track which arguments are used.  */
--  while (dollar_arguments_alloc < dollar_max_arg_used)
--    {
--      int nalloc;
--      nalloc = 2 * dollar_arguments_alloc + 16;
--      dollar_arguments_used = xrealloc (dollar_arguments_used, nalloc);
--      dollar_arguments_pointer_p = xrealloc (dollar_arguments_pointer_p,
--					     nalloc);
--      memset (dollar_arguments_used + dollar_arguments_alloc, 0,
--	      nalloc - dollar_arguments_alloc);
--      dollar_arguments_alloc = nalloc;
--    }
--  if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
--      && dollar_arguments_used[argnum - 1] == 1)
--    {
--      dollar_arguments_used[argnum - 1] = 2;
--      status_warning (status,
--		      "format argument %d used more than once in %s format",
--		      argnum, fki->name);
--    }
--  else
--    dollar_arguments_used[argnum - 1] = 1;
--  if (dollar_first_arg_num)
--    {
--      int i;
--      *param_ptr = params;
--      for (i = 1; i < argnum && *param_ptr != 0; i++)
--	*param_ptr = TREE_CHAIN (*param_ptr);
--
--      if (*param_ptr == 0)
--	{
--	  /* This case shouldn't be caught here.  */
--	  abort ();
--	}
--    }
--  else
--    *param_ptr = 0;
--  return argnum;
--}
--
--
--/* Finish the checking for a format string that used $ operand number formats
--   instead of non-$ formats.  We check for unused operands before used ones
--   (a serious error, since the implementation of the format function
--   can't know what types to pass to va_arg to find the later arguments).
--   and for unused operands at the end of the format (if we know how many
--   arguments the format had, so not for vprintf).  If there were operand
--   numbers out of range on a non-vprintf-style format, we won't have reached
--   here.  If POINTER_GAP_OK, unused arguments are OK if all arguments are
--   pointers.  */
--
--static void
--finish_dollar_format_checking (int *status, format_check_results *res, int pointer_gap_ok)
--{
--  int i;
--  bool found_pointer_gap = false;
--  for (i = 0; i < dollar_max_arg_used; i++)
--    {
--      if (!dollar_arguments_used[i])
--	{
--	  if (pointer_gap_ok && (dollar_first_arg_num == 0
--				 || dollar_arguments_pointer_p[i]))
--	    found_pointer_gap = true;
--	  else
--	    status_warning (status, "format argument %d unused before used argument %d in $-style format",
--			    i + 1, dollar_max_arg_used);
--	}
--    }
--  if (found_pointer_gap
--      || (dollar_first_arg_num
--	  && dollar_max_arg_used < dollar_arguments_count))
--    {
--      res->number_other--;
--      res->number_dollar_extra_args++;
--    }
--}
--
--
--/* Retrieve the specification for a format flag.  SPEC contains the
--   specifications for format flags for the applicable kind of format.
--   FLAG is the flag in question.  If PREDICATES is NULL, the basic
--   spec for that flag must be retrieved and this function aborts if
--   it cannot be found.  If PREDICATES is not NULL, it is a string listing
--   possible predicates for the spec entry; if an entry predicated on any
--   of these is found, it is returned, otherwise NULL is returned.  */
--
--static const format_flag_spec *
--get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
--{
--  int i;
--  for (i = 0; spec[i].flag_char != 0; i++)
--    {
--      if (spec[i].flag_char != flag)
--	continue;
--      if (predicates != NULL)
--	{
--	  if (spec[i].predicate != 0
--	      && strchr (predicates, spec[i].predicate) != 0)
--	    return &spec[i];
--	}
--      else if (spec[i].predicate == 0)
--	return &spec[i];
--    }
--  if (predicates == NULL)
--    abort ();
--  else
--    return NULL;
--}
--
--
--/* Check the argument list of a call to printf, scanf, etc.
--   INFO points to the function_format_info structure.
--   PARAMS is the list of argument values.  */
--
--static void
--check_format_info (int *status, function_format_info *info, tree params)
--{
--  format_check_context format_ctx;
--  unsigned HOST_WIDE_INT arg_num;
--  tree format_tree;
--  format_check_results res;
--  /* Skip to format argument.  If the argument isn't available, there's
--     no work for us to do; prototype checking will catch the problem.  */
--  for (arg_num = 1; ; ++arg_num)
--    {
--      if (params == 0)
--	return;
--      if (arg_num == info->format_num)
--	break;
--      params = TREE_CHAIN (params);
--    }
--  format_tree = TREE_VALUE (params);
--  params = TREE_CHAIN (params);
--  if (format_tree == 0)
--    return;
--
--  res.number_non_literal = 0;
--  res.number_extra_args = 0;
--  res.number_dollar_extra_args = 0;
--  res.number_wide = 0;
--  res.number_empty = 0;
--  res.number_unterminated = 0;
--  res.number_other = 0;
--
--  format_ctx.res = &res;
--  format_ctx.info = info;
--  format_ctx.params = params;
--  format_ctx.status = status;
--
--  check_function_arguments_recurse (check_format_arg, &format_ctx,
--				    format_tree, arg_num);
--
--  if (res.number_non_literal > 0)
--    {
--      /* Functions taking a va_list normally pass a non-literal format
--	 string.  These functions typically are declared with
--	 first_arg_num == 0, so avoid warning in those cases.  */
--      if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
--	{
--	  /* For strftime-like formats, warn for not checking the format
--	     string; but there are no arguments to check.  */
--	  if (warn_format_nonliteral)
--	    status_warning (status, "format not a string literal, format string not checked");
--	}
--      else if (info->first_arg_num != 0)
--	{
--	  /* If there are no arguments for the format at all, we may have
--	     printf (foo) which is likely to be a security hole.  */
--	  while (arg_num + 1 < info->first_arg_num)
--	    {
--	      if (params == 0)
--		break;
--	      params = TREE_CHAIN (params);
--	      ++arg_num;
--	    }
--	  if (params == 0 && (warn_format_nonliteral || warn_format_security))
--	    status_warning (status, "format not a string literal and no format arguments");
--	  else if (warn_format_nonliteral)
--	    status_warning (status, "format not a string literal, argument types not checked");
--	}
--    }
--
--  /* If there were extra arguments to the format, normally warn.  However,
--     the standard does say extra arguments are ignored, so in the specific
--     case where we have multiple leaves (conditional expressions or
--     ngettext) allow extra arguments if at least one leaf didn't have extra
--     arguments, but was otherwise OK (either non-literal or checked OK).
--     If the format is an empty string, this should be counted similarly to the
--     case of extra format arguments.  */
--  if (res.number_extra_args > 0 && res.number_non_literal == 0
--      && res.number_other == 0 && warn_format_extra_args)
--    status_warning (status, "too many arguments for format");
--  if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
--      && res.number_other == 0 && warn_format_extra_args)
--    status_warning (status, "unused arguments in $-style format");
--  if (res.number_empty > 0 && res.number_non_literal == 0
--      && res.number_other == 0 && warn_format_zero_length)
--    status_warning (status, "zero-length %s format string",
--		    format_types[info->format_type].name);
--
--  if (res.number_wide > 0)
--    status_warning (status, "format is a wide character string");
--
--  if (res.number_unterminated > 0)
--    status_warning (status, "unterminated format string");
--}
--
--/* Callback from check_function_arguments_recurse to check a
--   format string.  FORMAT_TREE is the format parameter.  ARG_NUM
--   is the number of the format argument.  CTX points to a
--   format_check_context.  */
--
--static void
--check_format_arg (void *ctx, tree format_tree,
--		  unsigned HOST_WIDE_INT arg_num)
--{
--  format_check_context *format_ctx = ctx;
--  format_check_results *res = format_ctx->res;
--  function_format_info *info = format_ctx->info;
--  tree params = format_ctx->params;
--  int *status = format_ctx->status;
--
--  int format_length;
--  HOST_WIDE_INT offset;
--  const char *format_chars;
--  tree array_size = 0;
--  tree array_init;
--
--  if (integer_zerop (format_tree))
--    {
--      /* Skip to first argument to check, so we can see if this format
--	 has any arguments (it shouldn't).  */
--      while (arg_num + 1 < info->first_arg_num)
--	{
--	  if (params == 0)
--	    return;
--	  params = TREE_CHAIN (params);
--	  ++arg_num;
--	}
--
--      if (params == 0)
--	res->number_other++;
--      else
--	res->number_extra_args++;
--
--      return;
--    }
--
--  offset = 0;
--  if (TREE_CODE (format_tree) == PLUS_EXPR)
--    {
--      tree arg0, arg1;
--
--      arg0 = TREE_OPERAND (format_tree, 0);
--      arg1 = TREE_OPERAND (format_tree, 1);
--      STRIP_NOPS (arg0);
--      STRIP_NOPS (arg1);
--      if (TREE_CODE (arg1) == INTEGER_CST)
--	format_tree = arg0;
--      else if (TREE_CODE (arg0) == INTEGER_CST)
--	{
--	  format_tree = arg1;
--	  arg1 = arg0;
--	}
--      else
--	{
--	  res->number_non_literal++;
--	  return;
--	}
--      if (!host_integerp (arg1, 0)
--	  || (offset = tree_low_cst (arg1, 0)) < 0)
--	{
--	  res->number_non_literal++;
--	  return;
--	}
--    }
--  if (TREE_CODE (format_tree) != ADDR_EXPR)
--    {
--      res->number_non_literal++;
--      return;
--    }
--  format_tree = TREE_OPERAND (format_tree, 0);
--  if (TREE_CODE (format_tree) == VAR_DECL
--      && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
--      && (array_init = decl_constant_value (format_tree)) != format_tree
--      && TREE_CODE (array_init) == STRING_CST)
--    {
--      /* Extract the string constant initializer.  Note that this may include
--	 a trailing NUL character that is not in the array (e.g.
--	 const char a[3] = "foo";).  */
--      array_size = DECL_SIZE_UNIT (format_tree);
--      format_tree = array_init;
--    }
--  if (TREE_CODE (format_tree) != STRING_CST)
--    {
--      res->number_non_literal++;
--      return;
--    }
--  if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
--    {
--      res->number_wide++;
--      return;
--    }
--  format_chars = TREE_STRING_POINTER (format_tree);
--  format_length = TREE_STRING_LENGTH (format_tree);
--  if (array_size != 0)
--    {
--      /* Variable length arrays can't be initialized.  */
--      if (TREE_CODE (array_size) != INTEGER_CST)
--	abort ();
--      if (host_integerp (array_size, 0))
--	{
--	  HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size);
--	  if (array_size_value > 0
--	      && array_size_value == (int) array_size_value
--	      && format_length > array_size_value)
--	    format_length = array_size_value;
--	}
--    }
--  if (offset)
--    {
--      if (offset >= format_length)
--	{
--	  res->number_non_literal++;
--	  return;
--	}
--      format_chars += offset;
--      format_length -= offset;
--    }
--  if (format_length < 1)
--    {
--      res->number_unterminated++;
--      return;
--    }
--  if (format_length == 1)
--    {
--      res->number_empty++;
--      return;
--    }
--  if (format_chars[--format_length] != 0)
--    {
--      res->number_unterminated++;
--      return;
--    }
--
--  /* Skip to first argument to check.  */
--  while (arg_num + 1 < info->first_arg_num)
--    {
--      if (params == 0)
--	return;
--      params = TREE_CHAIN (params);
--      ++arg_num;
--    }
--  /* Provisionally increment res->number_other; check_format_info_main
--     will decrement it if it finds there are extra arguments, but this way
--     need not adjust it for every return.  */
--  res->number_other++;
--  check_format_info_main (status, res, info, format_chars, format_length,
--			  params, arg_num);
--}
--
--
--/* Do the main part of checking a call to a format function.  FORMAT_CHARS
--   is the NUL-terminated format string (which at this point may contain
--   internal NUL characters); FORMAT_LENGTH is its length (excluding the
--   terminating NUL character).  ARG_NUM is one less than the number of
--   the first format argument to check; PARAMS points to that format
--   argument in the list of arguments.  */
--
--static void
--check_format_info_main (int *status, format_check_results *res,
--			function_format_info *info, const char *format_chars,
--			int format_length, tree params,
--			unsigned HOST_WIDE_INT arg_num)
--{
--  const char *orig_format_chars = format_chars;
--  tree first_fillin_param = params;
--
--  const format_kind_info *fki = &format_types[info->format_type];
--  const format_flag_spec *flag_specs = fki->flag_specs;
--  const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
--
--  /* -1 if no conversions taking an operand have been found; 0 if one has
--     and it didn't use $; 1 if $ formats are in use.  */
--  int has_operand_number = -1;
--
--  init_dollar_format_checking (info->first_arg_num, first_fillin_param);
--
--  while (1)
--    {
--      int i;
--      int suppressed = FALSE;
--      const char *length_chars = NULL;
--      enum format_lengths length_chars_val = FMT_LEN_none;
--      enum format_std_version length_chars_std = STD_C89;
--      int format_char;
--      tree cur_param;
--      tree wanted_type;
--      int main_arg_num = 0;
--      tree main_arg_params = 0;
--      enum format_std_version wanted_type_std;
--      const char *wanted_type_name;
--      format_wanted_type width_wanted_type;
--      format_wanted_type precision_wanted_type;
--      format_wanted_type main_wanted_type;
--      format_wanted_type *first_wanted_type = NULL;
--      format_wanted_type *last_wanted_type = NULL;
--      const format_length_info *fli = NULL;
--      const format_char_info *fci = NULL;
--      char flag_chars[256];
--      int aflag = 0;
--      if (*format_chars == 0)
--	{
--	  if (format_chars - orig_format_chars != format_length)
--	    status_warning (status, "embedded `\\0' in format");
--	  if (info->first_arg_num != 0 && params != 0
--	      && has_operand_number <= 0)
--	    {
--	      res->number_other--;
--	      res->number_extra_args++;
--	    }
--	  if (has_operand_number > 0)
--	    finish_dollar_format_checking (status, res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
--	  return;
--	}
--      if (*format_chars++ != '%')
--	continue;
--      if (*format_chars == 0)
--	{
--	  status_warning (status, "spurious trailing `%%' in format");
--	  continue;
--	}
--      if (*format_chars == '%')
--	{
--	  ++format_chars;
--	  continue;
--	}
--      flag_chars[0] = 0;
--
--      if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
--	{
--	  /* Possibly read a $ operand number at the start of the format.
--	     If one was previously used, one is required here.  If one
--	     is not used here, we can't immediately conclude this is a
--	     format without them, since it could be printf %m or scanf %*.  */
--	  int opnum;
--	  opnum = maybe_read_dollar_number (status, &format_chars, 0,
--					    first_fillin_param,
--					    &main_arg_params, fki);
--	  if (opnum == -1)
--	    return;
--	  else if (opnum > 0)
--	    {
--	      has_operand_number = 1;
--	      main_arg_num = opnum + info->first_arg_num - 1;
--	    }
--	}
--
--      /* Read any format flags, but do not yet validate them beyond removing
--	 duplicates, since in general validation depends on the rest of
--	 the format.  */
--      while (*format_chars != 0
--	     && strchr (fki->flag_chars, *format_chars) != 0)
--	{
--	  const format_flag_spec *s = get_flag_spec (flag_specs,
--						     *format_chars, NULL);
--	  if (strchr (flag_chars, *format_chars) != 0)
--	    {
--	      status_warning (status, "repeated %s in format", _(s->name));
--	    }
--	  else
--	    {
--	      i = strlen (flag_chars);
--	      flag_chars[i++] = *format_chars;
--	      flag_chars[i] = 0;
--	    }
--	  if (s->skip_next_char)
--	    {
--	      ++format_chars;
--	      if (*format_chars == 0)
--		{
--		  status_warning (status, "missing fill character at end of strfmon format");
--		  return;
--		}
--	    }
--	  ++format_chars;
--	}
--
--      /* Read any format width, possibly * or *m$.  */
--      if (fki->width_char != 0)
--	{
--	  if (fki->width_type != NULL && *format_chars == '*')
--	    {
--	      i = strlen (flag_chars);
--	      flag_chars[i++] = fki->width_char;
--	      flag_chars[i] = 0;
--	      /* "...a field width...may be indicated by an asterisk.
--		 In this case, an int argument supplies the field width..."  */
--	      ++format_chars;
--	      if (has_operand_number != 0)
--		{
--		  int opnum;
--		  opnum = maybe_read_dollar_number (status, &format_chars,
--						    has_operand_number == 1,
--						    first_fillin_param,
--						    &params, fki);
--		  if (opnum == -1)
--		    return;
--		  else if (opnum > 0)
--		    {
--		      has_operand_number = 1;
--		      arg_num = opnum + info->first_arg_num - 1;
--		    }
--		  else
--		    has_operand_number = 0;
--		}
--	      if (info->first_arg_num != 0)
--		{
--		  if (params == 0)
--		    {
--		      status_warning (status, "too few arguments for format");
--		      return;
--		    }
--		  cur_param = TREE_VALUE (params);
--		  if (has_operand_number <= 0)
--		    {
--		      params = TREE_CHAIN (params);
--		      ++arg_num;
--		    }
--		  width_wanted_type.wanted_type = *fki->width_type;
--		  width_wanted_type.wanted_type_name = NULL;
--		  width_wanted_type.pointer_count = 0;
--		  width_wanted_type.char_lenient_flag = 0;
--		  width_wanted_type.writing_in_flag = 0;
--		  width_wanted_type.reading_from_flag = 0;
--		  width_wanted_type.name = _("field width");
--		  width_wanted_type.param = cur_param;
--		  width_wanted_type.arg_num = arg_num;
--		  width_wanted_type.next = NULL;
--		  if (last_wanted_type != 0)
--		    last_wanted_type->next = &width_wanted_type;
--		  if (first_wanted_type == 0)
--		    first_wanted_type = &width_wanted_type;
--		  last_wanted_type = &width_wanted_type;
--		}
--	    }
--	  else
--	    {
--	      /* Possibly read a numeric width.  If the width is zero,
--		 we complain if appropriate.  */
--	      int non_zero_width_char = FALSE;
--	      int found_width = FALSE;
--	      while (ISDIGIT (*format_chars))
--		{
--		  found_width = TRUE;
--		  if (*format_chars != '0')
--		    non_zero_width_char = TRUE;
--		  ++format_chars;
--		}
--	      if (found_width && !non_zero_width_char &&
--		  (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
--		status_warning (status, "zero width in %s format",
--				fki->name);
--	      if (found_width)
--		{
--		  i = strlen (flag_chars);
--		  flag_chars[i++] = fki->width_char;
--		  flag_chars[i] = 0;
--		}
--	    }
--	}
--
--      /* Read any format left precision (must be a number, not *).  */
--      if (fki->left_precision_char != 0 && *format_chars == '#')
--	{
--	  ++format_chars;
--	  i = strlen (flag_chars);
--	  flag_chars[i++] = fki->left_precision_char;
--	  flag_chars[i] = 0;
--	  if (!ISDIGIT (*format_chars))
--	    status_warning (status, "empty left precision in %s format",
--			    fki->name);
--	  while (ISDIGIT (*format_chars))
--	    ++format_chars;
--	}
--
--      /* Read any format precision, possibly * or *m$.  */
--      if (fki->precision_char != 0 && *format_chars == '.')
--	{
--	  ++format_chars;
--	  i = strlen (flag_chars);
--	  flag_chars[i++] = fki->precision_char;
--	  flag_chars[i] = 0;
--	  if (fki->precision_type != NULL && *format_chars == '*')
--	    {
--	      /* "...a...precision...may be indicated by an asterisk.
--		 In this case, an int argument supplies the...precision."  */
--	      ++format_chars;
--	      if (has_operand_number != 0)
--		{
--		  int opnum;
--		  opnum = maybe_read_dollar_number (status, &format_chars,
--						    has_operand_number == 1,
--						    first_fillin_param,
--						    &params, fki);
--		  if (opnum == -1)
--		    return;
--		  else if (opnum > 0)
--		    {
--		      has_operand_number = 1;
--		      arg_num = opnum + info->first_arg_num - 1;
--		    }
--		  else
--		    has_operand_number = 0;
--		}
--	      if (info->first_arg_num != 0)
--		{
--		  if (params == 0)
--		    {
--		      status_warning (status, "too few arguments for format");
--		      return;
--		    }
--		  cur_param = TREE_VALUE (params);
--		  if (has_operand_number <= 0)
--		    {
--		      params = TREE_CHAIN (params);
--		      ++arg_num;
--		    }
--		  precision_wanted_type.wanted_type = *fki->precision_type;
--		  precision_wanted_type.wanted_type_name = NULL;
--		  precision_wanted_type.pointer_count = 0;
--		  precision_wanted_type.char_lenient_flag = 0;
--		  precision_wanted_type.writing_in_flag = 0;
--		  precision_wanted_type.reading_from_flag = 0;
--		  precision_wanted_type.name = _("field precision");
--		  precision_wanted_type.param = cur_param;
--		  precision_wanted_type.arg_num = arg_num;
--		  precision_wanted_type.next = NULL;
--		  if (last_wanted_type != 0)
--		    last_wanted_type->next = &precision_wanted_type;
--		  if (first_wanted_type == 0)
--		    first_wanted_type = &precision_wanted_type;
--		  last_wanted_type = &precision_wanted_type;
--		}
--	    }
--	  else
--	    {
--	      if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
--		  && !ISDIGIT (*format_chars))
--		status_warning (status, "empty precision in %s format",
--				fki->name);
--	      while (ISDIGIT (*format_chars))
--		++format_chars;
--	    }
--	}
--
--      /* Read any length modifier, if this kind of format has them.  */
--      fli = fki->length_char_specs;
--      length_chars = NULL;
--      length_chars_val = FMT_LEN_none;
--      length_chars_std = STD_C89;
--      if (fli)
--	{
--	  while (fli->name != 0 && fli->name[0] != *format_chars)
--	    fli++;
--	  if (fli->name != 0)
--	    {
--	      format_chars++;
--	      if (fli->double_name != 0 && fli->name[0] == *format_chars)
--		{
--		  format_chars++;
--		  length_chars = fli->double_name;
--		  length_chars_val = fli->double_index;
--		  length_chars_std = fli->double_std;
--		}
--	      else
--		{
--		  length_chars = fli->name;
--		  length_chars_val = fli->index;
--		  length_chars_std = fli->std;
--		}
--	      i = strlen (flag_chars);
--	      flag_chars[i++] = fki->length_code_char;
--	      flag_chars[i] = 0;
--	    }
--	  if (pedantic)
--	    {
--	      /* Warn if the length modifier is non-standard.  */
--	      if (ADJ_STD (length_chars_std) > C_STD_VER)
--		status_warning (status, "%s does not support the `%s' %s length modifier",
--				C_STD_NAME (length_chars_std), length_chars,
--				fki->name);
--	    }
--	}
--
--      /* Read any modifier (strftime E/O).  */
--      if (fki->modifier_chars != NULL)
--	{
--	  while (*format_chars != 0
--		 && strchr (fki->modifier_chars, *format_chars) != 0)
--	    {
--	      if (strchr (flag_chars, *format_chars) != 0)
--		{
--		  const format_flag_spec *s = get_flag_spec (flag_specs,
--							     *format_chars, NULL);
--		  status_warning (status, "repeated %s in format", _(s->name));
--		}
--	      else
--		{
--		  i = strlen (flag_chars);
--		  flag_chars[i++] = *format_chars;
--		  flag_chars[i] = 0;
--		}
--	      ++format_chars;
--	    }
--	}
--
--      /* Handle the scanf allocation kludge.  */
--      if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
--	{
--	  if (*format_chars == 'a' && !flag_isoc99)
--	    {
--	      if (format_chars[1] == 's' || format_chars[1] == 'S'
--		  || format_chars[1] == '[')
--		{
--		  /* `a' is used as a flag.  */
--		  i = strlen (flag_chars);
--		  flag_chars[i++] = 'a';
--		  flag_chars[i] = 0;
--		  format_chars++;
--		}
--	    }
--	}
--
--      format_char = *format_chars;
--      if (format_char == 0
--	  || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
--	      && format_char == '%'))
--	{
--	  status_warning (status, "conversion lacks type at end of format");
--	  continue;
--	}
--      format_chars++;
--      fci = fki->conversion_specs;
--      while (fci->format_chars != 0
--	     && strchr (fci->format_chars, format_char) == 0)
--	  ++fci;
--      if (fci->format_chars == 0)
--	{
--          if (ISGRAPH(format_char))
--	    status_warning (status, "unknown conversion type character `%c' in format",
--		     format_char);
--	  else
--	    status_warning (status, "unknown conversion type character 0x%x in format",
--		     format_char);
--	  continue;
--	}
--      if (pedantic)
--	{
--	  if (ADJ_STD (fci->std) > C_STD_VER)
--	    status_warning (status, "%s does not support the `%%%c' %s format",
--			    C_STD_NAME (fci->std), format_char, fki->name);
--	}
--
--      /* Validate the individual flags used, removing any that are invalid.  */
--      {
--	int d = 0;
--	for (i = 0; flag_chars[i] != 0; i++)
--	  {
--	    const format_flag_spec *s = get_flag_spec (flag_specs,
--						       flag_chars[i], NULL);
--	    flag_chars[i - d] = flag_chars[i];
--	    if (flag_chars[i] == fki->length_code_char)
--	      continue;
--	    if (strchr (fci->flag_chars, flag_chars[i]) == 0)
--	      {
--		status_warning (status, "%s used with `%%%c' %s format",
--				_(s->name), format_char, fki->name);
--		d++;
--		continue;
--	      }
--	    if (pedantic)
--	      {
--		const format_flag_spec *t;
--		if (ADJ_STD (s->std) > C_STD_VER)
--		  status_warning (status, "%s does not support %s",
--				  C_STD_NAME (s->std), _(s->long_name));
--		t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
--		if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
--		  {
--		    const char *long_name = (t->long_name != NULL
--					     ? t->long_name
--					     : s->long_name);
--		    if (ADJ_STD (t->std) > C_STD_VER)
--		      status_warning (status, "%s does not support %s with the `%%%c' %s format",
--				      C_STD_NAME (t->std), _(long_name),
--				      format_char, fki->name);
--		  }
--	      }
--	  }
--	flag_chars[i - d] = 0;
--      }
--
--      if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
--	  && strchr (flag_chars, 'a') != 0)
--	aflag = 1;
--
--      if (fki->suppression_char
--	  && strchr (flag_chars, fki->suppression_char) != 0)
--	suppressed = 1;
--
--      /* Validate the pairs of flags used.  */
--      for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
--	{
--	  const format_flag_spec *s, *t;
--	  if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
--	    continue;
--	  if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
--	    continue;
--	  if (bad_flag_pairs[i].predicate != 0
--	      && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
--	    continue;
--	  s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
--	  t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
--	  if (bad_flag_pairs[i].ignored)
--	    {
--	      if (bad_flag_pairs[i].predicate != 0)
--		status_warning (status, "%s ignored with %s and `%%%c' %s format",
--				_(s->name), _(t->name), format_char,
--				fki->name);
--	      else
--		status_warning (status, "%s ignored with %s in %s format",
--				_(s->name), _(t->name), fki->name);
--	    }
--	  else
--	    {
--	      if (bad_flag_pairs[i].predicate != 0)
--		status_warning (status, "use of %s and %s together with `%%%c' %s format",
--				_(s->name), _(t->name), format_char,
--				fki->name);
--	      else
--		status_warning (status, "use of %s and %s together in %s format",
--				_(s->name), _(t->name), fki->name);
--	    }
--	}
--
--      /* Give Y2K warnings.  */
--      if (warn_format_y2k)
--	{
--	  int y2k_level = 0;
--	  if (strchr (fci->flags2, '4') != 0)
--	    if (strchr (flag_chars, 'E') != 0)
--	      y2k_level = 3;
--	    else
--	      y2k_level = 2;
--	  else if (strchr (fci->flags2, '3') != 0)
--	    y2k_level = 3;
--	  else if (strchr (fci->flags2, '2') != 0)
--	    y2k_level = 2;
--	  if (y2k_level == 3)
--	    status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
--			    format_char);
--	  else if (y2k_level == 2)
--	    status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
--	}
--
--      if (strchr (fci->flags2, '[') != 0)
--	{
--	  /* Skip over scan set, in case it happens to have '%' in it.  */
--	  if (*format_chars == '^')
--	    ++format_chars;
--	  /* Find closing bracket; if one is hit immediately, then
--	     it's part of the scan set rather than a terminator.  */
--	  if (*format_chars == ']')
--	    ++format_chars;
--	  while (*format_chars && *format_chars != ']')
--	    ++format_chars;
--	  if (*format_chars != ']')
--	    /* The end of the format string was reached.  */
--	    status_warning (status, "no closing `]' for `%%[' format");
--	}
--
--      wanted_type = 0;
--      wanted_type_name = 0;
--      if (fki->flags & (int) FMT_FLAG_ARG_CONVERT)
--	{
--	  wanted_type = (fci->types[length_chars_val].type
--			 ? *fci->types[length_chars_val].type : 0);
--	  wanted_type_name = fci->types[length_chars_val].name;
--	  wanted_type_std = fci->types[length_chars_val].std;
--	  if (wanted_type == 0)
--	    {
--	      status_warning (status, "use of `%s' length modifier with `%c' type character",
--			      length_chars, format_char);
--	      /* Heuristic: skip one argument when an invalid length/type
--		 combination is encountered.  */
--	      arg_num++;
--	      if (params == 0)
--		{
--		  status_warning (status, "too few arguments for format");
--		  return;
--		}
--	      params = TREE_CHAIN (params);
--	      continue;
--	    }
--	  else if (pedantic
--		   /* Warn if non-standard, provided it is more non-standard
--		      than the length and type characters that may already
--		      have been warned for.  */
--		   && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
--		   && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
--	    {
--	      if (ADJ_STD (wanted_type_std) > C_STD_VER)
--		status_warning (status, "%s does not support the `%%%s%c' %s format",
--				C_STD_NAME (wanted_type_std), length_chars,
--				format_char, fki->name);
--	    }
--	}
--
--      /* Finally. . .check type of argument against desired type!  */
--      if (info->first_arg_num == 0)
--	continue;
--      if ((fci->pointer_count == 0 && wanted_type == void_type_node)
--	  || suppressed)
--	{
--	  if (main_arg_num != 0)
--	    {
--	      if (suppressed)
--		status_warning (status, "operand number specified with suppressed assignment");
--	      else
--		status_warning (status, "operand number specified for format taking no argument");
--	    }
--	}
--      else
--	{
--	  if (main_arg_num != 0)
--	    {
--	      arg_num = main_arg_num;
--	      params = main_arg_params;
--	    }
--	  else
--	    {
--	      ++arg_num;
--	      if (has_operand_number > 0)
--		{
--		  status_warning (status, "missing $ operand number in format");
--		  return;
--		}
--	      else
--		has_operand_number = 0;
--	      if (params == 0)
--		{
--		  status_warning (status, "too few arguments for format");
--		  return;
--		}
--	    }
--	  cur_param = TREE_VALUE (params);
--	  params = TREE_CHAIN (params);
--	  main_wanted_type.wanted_type = wanted_type;
--	  main_wanted_type.wanted_type_name = wanted_type_name;
--	  main_wanted_type.pointer_count = fci->pointer_count + aflag;
--	  main_wanted_type.char_lenient_flag = 0;
--	  if (strchr (fci->flags2, 'c') != 0)
--	    main_wanted_type.char_lenient_flag = 1;
--	  main_wanted_type.writing_in_flag = 0;
--	  main_wanted_type.reading_from_flag = 0;
--	  if (aflag)
--	    main_wanted_type.writing_in_flag = 1;
--	  else
--	    {
--	      if (strchr (fci->flags2, 'W') != 0)
--		main_wanted_type.writing_in_flag = 1;
--	      if (strchr (fci->flags2, 'R') != 0)
--		main_wanted_type.reading_from_flag = 1;
--	    }
--	  main_wanted_type.name = NULL;
--	  main_wanted_type.param = cur_param;
--	  main_wanted_type.arg_num = arg_num;
--	  main_wanted_type.next = NULL;
--	  if (last_wanted_type != 0)
--	    last_wanted_type->next = &main_wanted_type;
--	  if (first_wanted_type == 0)
--	    first_wanted_type = &main_wanted_type;
--	  last_wanted_type = &main_wanted_type;
--	}
--
--      if (first_wanted_type != 0)
--	check_format_types (status, first_wanted_type);
--
--    }
--}
--
--
--/* Check the argument types from a single format conversion (possibly
--   including width and precision arguments).  */
--static void
--check_format_types (int *status, format_wanted_type *types)
--{
--  for (; types != 0; types = types->next)
--    {
--      tree cur_param;
--      tree cur_type;
--      tree orig_cur_type;
--      tree wanted_type;
--      int arg_num;
--      int i;
--      int char_type_flag;
--      cur_param = types->param;
--      cur_type = TREE_TYPE (cur_param);
--      if (cur_type == error_mark_node)
--	continue;
--      char_type_flag = 0;
--      wanted_type = types->wanted_type;
--      arg_num = types->arg_num;
--
--      /* The following should not occur here.  */
--      if (wanted_type == 0)
--	abort ();
--      if (wanted_type == void_type_node && types->pointer_count == 0)
--	abort ();
--
--      if (types->pointer_count == 0)
--	wanted_type = (*lang_hooks.types.type_promotes_to) (wanted_type);
--
--      STRIP_NOPS (cur_param);
--
--      /* Check the types of any additional pointer arguments
--	 that precede the "real" argument.  */
--      for (i = 0; i < types->pointer_count; ++i)
--	{
--	  if (TREE_CODE (cur_type) == POINTER_TYPE)
--	    {
--	      cur_type = TREE_TYPE (cur_type);
--	      if (cur_type == error_mark_node)
--		break;
--
--	      /* Check for writing through a NULL pointer.  */
--	      if (types->writing_in_flag
--		  && i == 0
--		  && cur_param != 0
--		  && integer_zerop (cur_param))
--		status_warning (status,
--				"writing through null pointer (arg %d)",
--				arg_num);
--
--	      /* Check for reading through a NULL pointer.  */
--	      if (types->reading_from_flag
--		  && i == 0
--		  && cur_param != 0
--		  && integer_zerop (cur_param))
--		status_warning (status,
--				"reading through null pointer (arg %d)",
--				arg_num);
--
--	      if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
--		cur_param = TREE_OPERAND (cur_param, 0);
--	      else
--		cur_param = 0;
--
--	      /* See if this is an attempt to write into a const type with
--		 scanf or with printf "%n".  Note: the writing in happens
--		 at the first indirection only, if for example
--		 void * const * is passed to scanf %p; passing
--		 const void ** is simply passing an incompatible type.  */
--	      if (types->writing_in_flag
--		  && i == 0
--		  && (TYPE_READONLY (cur_type)
--		      || (cur_param != 0
--			  && (TREE_CODE_CLASS (TREE_CODE (cur_param)) == 'c'
--			      || (DECL_P (cur_param)
--				  && TREE_READONLY (cur_param))))))
--		status_warning (status, "writing into constant object (arg %d)", arg_num);
--
--	      /* If there are extra type qualifiers beyond the first
--		 indirection, then this makes the types technically
--		 incompatible.  */
--	      if (i > 0
--		  && pedantic
--		  && (TYPE_READONLY (cur_type)
--		      || TYPE_VOLATILE (cur_type)
--		      || TYPE_RESTRICT (cur_type)))
--		status_warning (status, "extra type qualifiers in format argument (arg %d)",
--			 arg_num);
--
--	    }
--	  else
--	    {
--	      if (types->pointer_count == 1)
--		status_warning (status, "format argument is not a pointer (arg %d)", arg_num);
--	      else
--		status_warning (status, "format argument is not a pointer to a pointer (arg %d)", arg_num);
--	      break;
--	    }
--	}
--
--      if (i < types->pointer_count)
--	continue;
--
--      orig_cur_type = cur_type;
--      cur_type = TYPE_MAIN_VARIANT (cur_type);
--
--      /* Check whether the argument type is a character type.  This leniency
--	 only applies to certain formats, flagged with 'c'.
--      */
--      if (types->char_lenient_flag)
--	char_type_flag = (cur_type == char_type_node
--			  || cur_type == signed_char_type_node
--			  || cur_type == unsigned_char_type_node);
--
--      /* Check the type of the "real" argument, if there's a type we want.  */
--      if (wanted_type == cur_type)
--	continue;
--      /* If we want `void *', allow any pointer type.
--	 (Anything else would already have got a warning.)
--	 With -pedantic, only allow pointers to void and to character
--	 types.  */
--      if (wanted_type == void_type_node
--	  && (!pedantic || (i == 1 && char_type_flag)))
--	continue;
--      /* Don't warn about differences merely in signedness, unless
--	 -pedantic.  With -pedantic, warn if the type is a pointer
--	 target and not a character type, and for character types at
--	 a second level of indirection.  */
--      if (TREE_CODE (wanted_type) == INTEGER_TYPE
--	  && TREE_CODE (cur_type) == INTEGER_TYPE
--	  && (! pedantic || i == 0 || (i == 1 && char_type_flag))
--	  && (TREE_UNSIGNED (wanted_type)
--	      ? wanted_type == c_common_unsigned_type (cur_type)
--	      : wanted_type == c_common_signed_type (cur_type)))
--	continue;
--      /* Likewise, "signed char", "unsigned char" and "char" are
--	 equivalent but the above test won't consider them equivalent.  */
--      if (wanted_type == char_type_node
--	  && (! pedantic || i < 2)
--	  && char_type_flag)
--	continue;
--      /* Now we have a type mismatch.  */
--      {
--	const char *this;
--	const char *that;
--	tree tmp;
--
--	tmp = TYPE_NAME (wanted_type);
--	if (TREE_CODE (tmp) == TYPE_DECL)
--	  tmp = DECL_NAME (tmp);
--	this = IDENTIFIER_POINTER (tmp);
--
--	that = 0;
--	if (TYPE_NAME (orig_cur_type) != 0
--	    && TREE_CODE (orig_cur_type) != INTEGER_TYPE
--	    && !(TREE_CODE (orig_cur_type) == POINTER_TYPE
--		 && TREE_CODE (TREE_TYPE (orig_cur_type)) == INTEGER_TYPE))
--	  {
--	    tmp = TYPE_NAME (orig_cur_type);
--	    if (TREE_CODE (tmp) == TYPE_DECL)
--	      tmp = DECL_NAME (tmp);
--	    if (tmp)
--	      that = IDENTIFIER_POINTER (tmp);
--	  }
--
--	/* A nameless type can't possibly match what the format wants.
--	   So there will be a warning for it.
--	   Make up a string to describe vaguely what it is.  */
--	if (that == 0)
--	  {
--	    if (TREE_CODE (orig_cur_type) == POINTER_TYPE)
--	      that = _("pointer");
--	    else
--	      that = _("different type");
--	  }
--
--	/* Make the warning better in case of mismatch of int vs long.  */
--	if (TREE_CODE (orig_cur_type) == INTEGER_TYPE
--	    && TREE_CODE (wanted_type) == INTEGER_TYPE
--	    && TYPE_PRECISION (orig_cur_type) == TYPE_PRECISION (wanted_type)
--	    && TYPE_NAME (orig_cur_type) != 0
--	    && TREE_CODE (TYPE_NAME (orig_cur_type)) == TYPE_DECL)
--	  that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (orig_cur_type)));
--
--	if (strcmp (this, that) != 0)
--	  {
--	    /* There may be a better name for the format, e.g. size_t,
--	       but we should allow for programs with a perverse typedef
--	       making size_t something other than what the compiler
--	       thinks.  */
--	    if (types->wanted_type_name != 0
--		&& strcmp (types->wanted_type_name, that) != 0)
--	      this = types->wanted_type_name;
--	    if (types->name != 0)
--	      status_warning (status, "%s is not type %s (arg %d)", types->name, this,
--		       arg_num);
--	    else
--	      status_warning (status, "%s format, %s arg (arg %d)", this, that, arg_num);
--	  }
--      }
--    }
--}
--
--/* Given a format_char_info array FCI, and a character C, this function
--   returns the index into the conversion_specs where that specifier's
--   data is located.  If the character isn't found it aborts.  */
--static unsigned int
--find_char_info_specifier_index (const format_char_info *fci, int c)
--{
--  unsigned int i = 0;
--  
--  while (fci->format_chars)
--    {
--      if (strchr (fci->format_chars, c))
--	return i;
--      i++; fci++;
--    }
--  
--  /* We shouldn't be looking for a non-existent specifier.  */
--  abort ();
--}
--
--/* Given a format_length_info array FLI, and a character C, this
--   function returns the index into the conversion_specs where that
--   modifier's data is located.  If the character isn't found it
--   aborts.  */
--static unsigned int
--find_length_info_modifier_index (const format_length_info *fli, int c)
--{
--  unsigned int i = 0;
--  
--  while (fli->name)
--    {
--      if (strchr (fli->name, c))
--	return i;
--      i++; fli++;
--    }
--  
--  /* We shouldn't be looking for a non-existent modifier.  */
--  abort ();
--}
--
--/* Determine the type of HOST_WIDE_INT in the code being compiled for
--   use in GCC's __asm_fprintf__ custom format attribute.  You must
--   have set dynamic_format_types before calling this function.  */
--static void
--init_dynamic_asm_fprintf_info (void)
--{
--  static tree hwi;
--      
--  if (!hwi)
--    {
--      format_length_info *new_asm_fprintf_length_specs;
--      unsigned int i;
--	  
--      /* Find the underlying type for HOST_WIDE_INT.  For the %w
--	 length modifier to work, one must have issued: "typedef
--	 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
--	 prior to using that modifier.  */
--      hwi = maybe_get_identifier ("__gcc_host_wide_int__");
--      if (!hwi)
--	{
--	  error ("'__gcc_host_wide_int__' is not defined as a type");
--	  return;
--	}
--      hwi = identifier_global_value (hwi);
--      if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
--	{
--	  error ("'__gcc_host_wide_int__' is not defined as a type");
--	  return;
--	}
--      hwi = DECL_ORIGINAL_TYPE (hwi);
--      if (!hwi)
--	abort ();
--      if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
--	{
--	  error ("'__gcc_host_wide_int__' is not defined as 'long'"
--		 " or 'long long'");
--	  return;
--	}
--
--      /* Create a new (writable) copy of asm_fprintf_length_specs.  */
--      new_asm_fprintf_length_specs = xmemdup (asm_fprintf_length_specs,
--					      sizeof (asm_fprintf_length_specs),
--					      sizeof (asm_fprintf_length_specs));
--
--      /* HOST_WIDE_INT must be one of 'long' or 'long long'.  */
--      i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
--      if (hwi == long_integer_type_node)
--	new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
--      else if (hwi == long_long_integer_type_node)
--	new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
--      else
--	abort ();
--
--      /* Assign the new data for use.  */
--      dynamic_format_types[asm_fprintf_format_type].length_char_specs =
--	new_asm_fprintf_length_specs;
--    }
--}
--
--/* Determine the types of "tree" and "location_t" in the code being
--   compiled for use in GCC's diagnostic custom format attributes.  You
--   must have set dynamic_format_types before calling this function.  */
--static void
--init_dynamic_diag_info (void)
--{
--  static tree t, loc, hwi;
--      
--  if (!loc || !t || !hwi)
--    {
--      static format_char_info *diag_fci, *cdiag_fci, *cxxdiag_fci;
--      static format_length_info *diag_ls;
--      unsigned int i;
--
--      /* For the GCC-diagnostics custom format specifiers to work, one
--	 must have declared `tree' and/or `location_t' prior to using
--	 those attributes.  If we haven't seen these declarations then
--	 you shouldn't use the specifiers requiring these types.
--	 However we don't force a hard ICE because we may see only one
--	 or the other type.  */
--      if ((loc = maybe_get_identifier ("location_t")))
--	{
--	  loc = identifier_global_value (loc);
--	  if (loc)
--	    {
--	      if (TREE_CODE (loc) != TYPE_DECL)
--		{
--		  error ("'location_t' is not defined as a type");
--		  loc = 0;
--		}
--	      else
--		loc = TREE_TYPE (loc);
--	    }
--	}
--
--      /* We need to grab the underlying `union tree_node' so peek into
--	 an extra type level.  */
--      if ((t = maybe_get_identifier ("tree")))
--	{
--	  t = identifier_global_value (t);
--	  if (t)
--	    {
--	      if (TREE_CODE (t) != TYPE_DECL)
--		{
--		  error ("'tree' is not defined as a type");
--		  t = 0;
--		}
--	      else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
--		{
--		  error ("'tree' is not defined as a pointer type");
--		  t = 0;
--		}
--	      else
--		t = TREE_TYPE (TREE_TYPE (t));
--	    }
--	}
--    
--      /* Find the underlying type for HOST_WIDE_INT.  For the %w
--	 length modifier to work, one must have issued: "typedef
--	 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
--	 prior to using that modifier.  */
--      if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
--	{
--	  hwi = identifier_global_value (hwi);
--	  if (hwi)
--	    {
--	      if (TREE_CODE (hwi) != TYPE_DECL)
--		{
--		  error ("'__gcc_host_wide_int__' is not defined as a type");
--		  hwi = 0;
--		}
--	      else
--		{
--		  hwi = DECL_ORIGINAL_TYPE (hwi);
--		  if (!hwi)
--		    abort ();
--		  if (hwi != long_integer_type_node
--		      && hwi != long_long_integer_type_node)
--		    {
--		      error ("'__gcc_host_wide_int__' is not defined"
--			     " as 'long' or 'long long'");
--		      hwi = 0;
--		    }
--		}
--	    }
--	}
--      
--      /* Assign the new data for use.  */
--
--      /* All the GCC diag formats use the same length specs.  */
--      if (! diag_ls)
--	dynamic_format_types[gcc_diag_format_type].length_char_specs =
--	  dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
--	  dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
--	  diag_ls = xmemdup (gcc_diag_length_specs,
--			     sizeof (gcc_diag_length_specs),
--			     sizeof (gcc_diag_length_specs)); 
--      if (hwi)
--        {
--	  /* HOST_WIDE_INT must be one of 'long' or 'long long'.  */
--	  i = find_length_info_modifier_index (diag_ls, 'w');
--	  if (hwi == long_integer_type_node)
--	    diag_ls[i].index = FMT_LEN_l;
--	  else if (hwi == long_long_integer_type_node)
--	    diag_ls[i].index = FMT_LEN_ll;
--	  else
--	    abort ();
--	}
--
--      /* Handle the __gcc_diag__ format specifics.  */
--      if (! diag_fci)
--	dynamic_format_types[gcc_diag_format_type].conversion_specs =
--	  diag_fci = xmemdup (gcc_diag_char_table,
--			      sizeof(gcc_diag_char_table),
--			      sizeof(gcc_diag_char_table));
--      if (loc)
--        {
--	  i = find_char_info_specifier_index (diag_fci, 'H');
--	  diag_fci[i].types[0].type = &loc;
--	  diag_fci[i].pointer_count = 1;
--	}
--      if (t)
--        {
--	  i = find_char_info_specifier_index (diag_fci, 'J');
--	  diag_fci[i].types[0].type = &t;
--	  diag_fci[i].pointer_count = 1;
--	}
--
--      /* Handle the __gcc_cdiag__ format specifics.  */
--      if (! cdiag_fci)
--	dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
--	  cdiag_fci = xmemdup (gcc_cdiag_char_table,
--			       sizeof(gcc_cdiag_char_table),
--			       sizeof(gcc_cdiag_char_table));
--      if (loc)
--        {
--	  i = find_char_info_specifier_index (cdiag_fci, 'H');
--	  cdiag_fci[i].types[0].type = &loc;
--	  cdiag_fci[i].pointer_count = 1;
--	}
--      if (t)
--        {
--	  /* All specifiers taking a tree share the same struct.  */
--	  i = find_char_info_specifier_index (cdiag_fci, 'D');
--	  cdiag_fci[i].types[0].type = &t;
--	  cdiag_fci[i].pointer_count = 1;
--	  i = find_char_info_specifier_index (cdiag_fci, 'J');
--	  cdiag_fci[i].types[0].type = &t;
--	  cdiag_fci[i].pointer_count = 1;
--	}
--
--      /* Handle the __gcc_cxxdiag__ format specifics.  */
--      if (! cxxdiag_fci)
--	dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
--	  cxxdiag_fci = xmemdup (gcc_cxxdiag_char_table,
--				 sizeof(gcc_cxxdiag_char_table),
--				 sizeof(gcc_cxxdiag_char_table));
--      if (loc)
--        {
--	  i = find_char_info_specifier_index (cxxdiag_fci, 'H');
--	  cxxdiag_fci[i].types[0].type = &loc;
--	  cxxdiag_fci[i].pointer_count = 1;
--	}
--      if (t)
--        {
--	  /* All specifiers taking a tree share the same struct.  */
--	  i = find_char_info_specifier_index (cxxdiag_fci, 'D');
--	  cxxdiag_fci[i].types[0].type = &t;
--	  cxxdiag_fci[i].pointer_count = 1;
--	  i = find_char_info_specifier_index (cxxdiag_fci, 'J');
--	  cxxdiag_fci[i].types[0].type = &t;
--	  cxxdiag_fci[i].pointer_count = 1;
--	}
--    }
--}
--
--/* Handle a "format" attribute; arguments as in
--   struct attribute_spec.handler.  */
--tree
--handle_format_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
--			 int flags, bool *no_add_attrs)
--{
--  tree type = *node;
--  function_format_info info;
--  tree argument;
--
--  if (!decode_format_attr (args, &info, 0))
--    {
--      *no_add_attrs = true;
--      return NULL_TREE;
--    }
--
--  argument = TYPE_ARG_TYPES (type);
--  if (argument)
--    {
--      if (!check_format_string (argument, info.format_num, flags,
--				no_add_attrs))
--	return NULL_TREE;
--
--      if (info.first_arg_num != 0)
--	{
--	  unsigned HOST_WIDE_INT arg_num = 1;
--
--	  /* Verify that first_arg_num points to the last arg,
--	     the ...  */
--	  while (argument)
--	    arg_num++, argument = TREE_CHAIN (argument);
--
--	  if (arg_num != info.first_arg_num)
--	    {
--	      if (!(flags & (int) ATTR_FLAG_BUILT_IN))
--		error ("args to be formatted is not '...'");
--	      *no_add_attrs = true;
--	      return NULL_TREE;
--	    }
--	}
--    }
--
--  if (info.format_type == strftime_format_type && info.first_arg_num != 0)
--    {
--      error ("strftime formats cannot format arguments");
--      *no_add_attrs = true;
--      return NULL_TREE;
--    }
--
--  /* If this is a custom GCC-internal format type, we have to
--     initialize certain bits a runtime.  */
--  if (info.format_type == asm_fprintf_format_type
--      || info.format_type == gcc_diag_format_type
--      || info.format_type == gcc_cdiag_format_type
--      || info.format_type == gcc_cxxdiag_format_type)
--    {
--      /* Our first time through, we have to make sure that our
--         format_type data is allocated dynamically and is modifiable.  */
--      if (!dynamic_format_types)
--	format_types = dynamic_format_types =
--	  xmemdup (format_types_orig, sizeof (format_types_orig),
--		   sizeof (format_types_orig));
--
--      /* If this is format __asm_fprintf__, we have to initialize
--         GCC's notion of HOST_WIDE_INT for checking %wd.  */
--      if (info.format_type == asm_fprintf_format_type)
--	init_dynamic_asm_fprintf_info();
--      /* If this is one of the diagnostic attributes, then we have to
--         initialize `location_t' and `tree' at runtime.  */
--      else if (info.format_type == gcc_diag_format_type
--	       || info.format_type == gcc_cdiag_format_type
--	       || info.format_type == gcc_cxxdiag_format_type)
--	init_dynamic_diag_info();
--      else
--	abort();
--    }
--
--  return NULL_TREE;
--}
-diff -ruN gcc-3.4.5-20060117-1/gcc/c-incpath.c.orig gcc-3.4.5-20060117-1-winelf/gcc/c-incpath.c.orig
---- gcc-3.4.5-20060117-1/gcc/c-incpath.c.orig	2004-05-31 03:37:47.000000000 -0700
-+++ gcc-3.4.5-20060117-1-winelf/gcc/c-incpath.c.orig	1969-12-31 16:00:00.000000000 -0800
-@@ -1,364 +0,0 @@
--/* Set up combined include path chain for the preprocessor.
--   Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
--   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
--
--   Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
--
--This program is free software; you can redistribute it and/or modify it
--under the terms of the GNU General Public License as published by the
--Free Software Foundation; either version 2, or (at your option) any
--later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--GNU General Public License for more details.
--
--You should have received a copy of the GNU General Public License
--along with this program; if not, write to the Free Software
--Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
--
--#include "config.h"
--#include "system.h"
--#include "coretypes.h"
--#include "tm.h"
--#include "cpplib.h"
--#include "prefix.h"
--#include "intl.h"
--#include "c-incpath.h"
--#include "cppdefault.h"
--
--/* Windows does not natively support inodes, and neither does MSDOS.
--   Cygwin's emulation can generate non-unique inodes, so don't use it.
--   VMS has non-numeric inodes.  */
--#ifdef VMS
--# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
--# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
--#else
--# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
--#  define INO_T_EQ(A, B) 0
--# else
--#  define INO_T_EQ(A, B) ((A) == (B))
--# endif
--# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
--#endif
--
--static void add_env_var_paths (const char *, int);
--static void add_standard_paths (const char *, const char *, int);
--static void free_path (struct cpp_dir *, int);
--static void merge_include_chains (cpp_reader *, int);
--static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
--					   struct cpp_dir *,
--					   struct cpp_dir *, int);
--
--/* Include chains heads and tails.  */
--static struct cpp_dir *heads[4];
--static struct cpp_dir *tails[4];
--static bool quote_ignores_source_dir;
--enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
--
--/* Free an element of the include chain, possibly giving a reason.  */
--static void
--free_path (struct cpp_dir *path, int reason)
--{
--  switch (reason)
--    {
--    case REASON_DUP:
--    case REASON_DUP_SYS:
--      fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
--      if (reason == REASON_DUP_SYS)
--	fprintf (stderr,
-- _("  as it is a non-system directory that duplicates a system directory\n"));
--      break;
--
--    case REASON_NOENT:
--      fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
--	       path->name);
--      break;
--
--    case REASON_QUIET:
--    default:
--      break;
--    }
--
--  free (path->name);
--  free (path);
--}
--
--/* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
--   append all the names to the search path CHAIN.  */
--static void
--add_env_var_paths (const char *env_var, int chain)
--{
--  char *p, *q, *path;
--
--  GET_ENVIRONMENT (q, env_var);
--
--  if (!q)
--    return;
--
--  for (p = q; *q; p = q + 1)
--    {
--      q = p;
--      while (*q != 0 && *q != PATH_SEPARATOR)
--	q++;
--
--      if (p == q)
--	path = xstrdup (".");
--      else
--	{
--	  path = xmalloc (q - p + 1);
--	  memcpy (path, p, q - p);
--	  path[q - p] = '\0';
--	}
--
--      add_path (path, chain, chain == SYSTEM);
--    }
--}
--
--/* Append the standard include chain defined in cppdefault.c.  */
--static void
--add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
--{
--  const struct default_include *p;
--  size_t len;
--
--  if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
--    {
--      /* Look for directories that start with the standard prefix.
--	 "Translate" them, ie. replace /usr/local/lib/gcc... with
--	 IPREFIX and search them first.  */
--      for (p = cpp_include_defaults; p->fname; p++)
--	{
--	  if (!p->cplusplus || cxx_stdinc)
--	    {
--	      /* Should we be translating sysrooted dirs too?  Assume
--		 that iprefix and sysroot are mutually exclusive, for
--		 now.  */
--	      if (sysroot && p->add_sysroot)
--		continue;
--	      if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
--		{
--		  char *str = concat (iprefix, p->fname + len, NULL);
--		  add_path (str, SYSTEM, p->cxx_aware);
--		}
--	    }
--	}
--    }
--
--  for (p = cpp_include_defaults; p->fname; p++)
--    {
--      if (!p->cplusplus || cxx_stdinc)
--	{
--	  char *str;
--
--	  /* Should this directory start with the sysroot?  */
--	  if (sysroot && p->add_sysroot)
--	    str = concat (sysroot, p->fname, NULL);
--	  else
--	    str = update_path (p->fname, p->component);
--
--	  add_path (str, SYSTEM, p->cxx_aware);
--	}
--    }
--}
--
--/* For each duplicate path in chain HEAD, keep just the first one.
--   Remove each path in chain HEAD that also exists in chain SYSTEM.
--   Set the NEXT pointer of the last path in the resulting chain to
--   JOIN, unless it duplicates JOIN in which case the last path is
--   removed.  Return the head of the resulting chain.  Any of HEAD,
--   JOIN and SYSTEM can be NULL.  */
--static struct cpp_dir *
--remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
--		   struct cpp_dir *system, struct cpp_dir *join,
--		   int verbose)
--{
--  struct cpp_dir **pcur, *tmp, *cur;
--  struct stat st;
--
--  for (pcur = &head; *pcur; )
--    {
--      int reason = REASON_QUIET;
--
--      cur = *pcur;
--
--      if (stat (cur->name, &st))
--	{
--	  /* Dirs that don't exist are silently ignored, unless verbose.  */
--	  if (errno != ENOENT)
--	    cpp_errno (pfile, CPP_DL_ERROR, cur->name);
--	  else
--	    reason = REASON_NOENT;
--	}
--      else if (!S_ISDIR (st.st_mode))
--	cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
--			     "%s: not a directory", cur->name);
--      else
--	{
--	  INO_T_COPY (cur->ino, st.st_ino);
--	  cur->dev  = st.st_dev;
--
--	  /* Remove this one if it is in the system chain.  */
--	  reason = REASON_DUP_SYS;
--	  for (tmp = system; tmp; tmp = tmp->next)
--	    if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev)
--	      break;
--
--	  if (!tmp)
--	    {
--	      /* Duplicate of something earlier in the same chain?  */
--	      reason = REASON_DUP;
--	      for (tmp = head; tmp != cur; tmp = tmp->next)
--		if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev)
--		  break;
--
--	      if (tmp == cur
--		  /* Last in the chain and duplicate of JOIN?  */
--		  && !(cur->next == NULL && join
--		       && INO_T_EQ (cur->ino, join->ino)
--		       && cur->dev == join->dev))
--		{
--		  /* Unique, so keep this directory.  */
--		  pcur = &cur->next;
--		  continue;
--		}
--	    }
--	}
--
--      /* Remove this entry from the chain.  */
--      *pcur = cur->next;
--      free_path (cur, verbose ? reason: REASON_QUIET);
--    }
--
--  *pcur = join;
--  return head;
--}
--
--/* Merge the four include chains together in the order quote, bracket,
--   system, after.  Remove duplicate dirs (as determined by
--   INO_T_EQ()).
--
--   We can't just merge the lists and then uniquify them because then
--   we may lose directories from the <> search path that should be
--   there; consider -Ifoo -Ibar -I- -Ifoo -Iquux.  It is however safe
--   to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo
--   -Iquux.  */
--static void
--merge_include_chains (cpp_reader *pfile, int verbose)
--{
--  /* Join the SYSTEM and AFTER chains.  Remove duplicates in the
--     resulting SYSTEM chain.  */
--  if (heads[SYSTEM])
--    tails[SYSTEM]->next = heads[AFTER];
--  else
--    heads[SYSTEM] = heads[AFTER];
--  heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);
--
--  /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
--     join it to SYSTEM.  */
--  heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
--				      heads[SYSTEM], verbose);
--
--  /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
--     join it to BRACKET.  */
--  heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
--				    heads[BRACKET], verbose);
--
--  /* If verbose, print the list of dirs to search.  */
--  if (verbose)
--    {
--      struct cpp_dir *p;
--
--      fprintf (stderr, _("#include \"...\" search starts here:\n"));
--      for (p = heads[QUOTE];; p = p->next)
--	{
--	  if (p == heads[BRACKET])
--	    fprintf (stderr, _("#include <...> search starts here:\n"));
--	  if (!p)
--	    break;
--	  fprintf (stderr, " %s\n", p->name);
--	}
--      fprintf (stderr, _("End of search list.\n"));
--    }
--}
--
--/* Use given -I paths for #include "..." but not #include <...>, and
--   don't search the directory of the present file for #include "...".
--   (Note that -I. -I- is not the same as the default setup; -I. uses
--   the compiler's working dir.)  */
--void
--split_quote_chain (void)
--{
--  heads[QUOTE] = heads[BRACKET];
--  tails[QUOTE] = tails[BRACKET];
--  heads[BRACKET] = NULL;
--  tails[BRACKET] = NULL;
--  /* This is NOT redundant.  */
--  quote_ignores_source_dir = true;
--}
--
--/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
--   NUL-terminated.  */
--void
--add_path (char *path, int chain, int cxx_aware)
--{
--  struct cpp_dir *p;
--
--#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
--  /* Convert all backslashes to slashes.  The native CRT stat()
--     function does not recognise a directory that ends in a backslash
--     (unless it is a drive root dir, such "c:\").  Forward slashes,
--     trailing or otherwise, cause no problems for stat().  */
--  char* c;
--  for (c = path; *c; c++)
--    if (*c == '\\') *c = '/';
--#endif
--
--  p = xmalloc (sizeof (struct cpp_dir));
--  p->next = NULL;
--  p->name = path;
--  if (chain == SYSTEM || chain == AFTER)
--    p->sysp = 1 + !cxx_aware;
--  else
--    p->sysp = 0;
--
--  if (tails[chain])
--    tails[chain]->next = p;
--  else
--    heads[chain] = p;
--  tails[chain] = p;
--}
--
--/* Exported function to handle include chain merging, duplicate
--   removal, and registration with cpplib.  */
--void
--register_include_chains (cpp_reader *pfile, const char *sysroot,
--			 const char *iprefix, int stdinc, int cxx_stdinc,
--			 int verbose)
--{
--  static const char *const lang_env_vars[] =
--    { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
--      "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
--  cpp_options *cpp_opts = cpp_get_options (pfile);
--  size_t idx = (cpp_opts->objc ? 2: 0);
--
--  if (cpp_opts->cplusplus)
--    idx++;
--  else
--    cxx_stdinc = false;
--
--  /* CPATH and language-dependent environment variables may add to the
--     include chain.  */
--  add_env_var_paths ("CPATH", BRACKET);
--  add_env_var_paths (lang_env_vars[idx], SYSTEM);
--
--  /* Finally chain on the standard directories.  */
--  if (stdinc)
--    add_standard_paths (sysroot, iprefix, cxx_stdinc);
--
--  merge_include_chains (pfile, verbose);
--
--  cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
--			  quote_ignores_source_dir);
--}
-diff -ruN gcc-3.4.5-20060117-1/gcc/collect2.c.orig gcc-3.4.5-20060117-1-winelf/gcc/collect2.c.orig
---- gcc-3.4.5-20060117-1/gcc/collect2.c.orig	2005-01-10 07:25:23.000000000 -0800
-+++ gcc-3.4.5-20060117-1-winelf/gcc/collect2.c.orig	1969-12-31 16:00:00.000000000 -0800
-@@ -1,2868 +0,0 @@
--/* Collect static initialization info into data structures that can be
--   traversed by C++ initialization and finalization routines.
--   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
--   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
--   Contributed by Chris Smith (csmith@convex.com).
--   Heavily modified by Michael Meissner (meissner@cygnus.com),
--   Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
--
--This file is part of GCC.
--
--GCC is free software; you can redistribute it and/or modify it under
--the terms of the GNU General Public License as published by the Free
--Software Foundation; either version 2, or (at your option) any later
--version.
--
--GCC is distributed in the hope that it will be useful, but WITHOUT ANY
--WARRANTY; without even the implied warranty of MERCHANTABILITY or
--FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
--for more details.
--
--You should have received a copy of the GNU General Public License
--along with GCC; see the file COPYING.  If not, write to the Free
--Software Foundation, 59 Temple Place - Suite 330, Boston, MA
--02111-1307, USA.  */
--
--
--/* Build tables of static constructors and destructors and run ld.  */
--
--#include "config.h"
--#include "system.h"
--#include "coretypes.h"
--#include "tm.h"
--#include <signal.h>
--#if ! defined( SIGCHLD ) && defined( SIGCLD )
--#  define SIGCHLD SIGCLD
--#endif
--
--#ifdef vfork /* Autoconf may define this to fork for us.  */
--# define VFORK_STRING "fork"
--#else
--# define VFORK_STRING "vfork"
--#endif
--#ifdef HAVE_VFORK_H
--#include <vfork.h>
--#endif
--#ifdef VMS
--#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \
--               lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1)
--#endif /* VMS */
--
--#ifndef LIBRARY_PATH_ENV
--#define LIBRARY_PATH_ENV "LIBRARY_PATH"
--#endif
--
--#define COLLECT
--
--#include "collect2.h"
--#include "demangle.h"
--#include "obstack.h"
--#include "intl.h"
--#include "version.h"
--
--/* On certain systems, we have code that works by scanning the object file
--   directly.  But this code uses system-specific header files and library
--   functions, so turn it off in a cross-compiler.  Likewise, the names of
--   the utilities are not correct for a cross-compiler; we have to hope that
--   cross-versions are in the proper directories.  */
--
--#ifdef CROSS_COMPILE
--#undef SUNOS4_SHARED_LIBRARIES
--#undef OBJECT_FORMAT_COFF
--#undef MD_EXEC_PREFIX
--#undef REAL_LD_FILE_NAME
--#undef REAL_NM_FILE_NAME
--#undef REAL_STRIP_FILE_NAME
--#endif
--
--/* If we cannot use a special method, use the ordinary one:
--   run nm to find what symbols are present.
--   In a cross-compiler, this means you need a cross nm,
--   but that is not quite as unpleasant as special headers.  */
--
--#if !defined (OBJECT_FORMAT_COFF)
--#define OBJECT_FORMAT_NONE
--#endif
--
--#ifdef OBJECT_FORMAT_COFF
--
--#include <a.out.h>
--#include <ar.h>
--
--#ifdef UMAX
--#include <sgs.h>
--#endif
--
--/* Many versions of ldfcn.h define these.  */
--#ifdef FREAD
--#undef FREAD
--#undef FWRITE
--#endif
--
--#include <ldfcn.h>
--
--/* Some systems have an ISCOFF macro, but others do not.  In some cases
--   the macro may be wrong.  MY_ISCOFF is defined in tm.h files for machines
--   that either do not have an ISCOFF macro in /usr/include or for those
--   where it is wrong.  */
--
--#ifndef MY_ISCOFF
--#define MY_ISCOFF(X) ISCOFF (X)
--#endif
--
--#endif /* OBJECT_FORMAT_COFF */
--
--#ifdef OBJECT_FORMAT_NONE
--
--/* Default flags to pass to nm.  */
--#ifndef NM_FLAGS
--#define NM_FLAGS "-n"
--#endif
--
--#endif /* OBJECT_FORMAT_NONE */
--
--/* Some systems use __main in a way incompatible with its use in gcc, in these
--   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
--   give the same symbol without quotes for an alternative entry point.  */
--#ifndef NAME__MAIN
--#define NAME__MAIN "__main"
--#endif
--
--/* This must match tree.h.  */
--#define DEFAULT_INIT_PRIORITY 65535
--
--#ifndef COLLECT_SHARED_INIT_FUNC
--#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \
--  fprintf ((STREAM), "void _GLOBAL__DI() {\n\t%s();\n}\n", (FUNC))
--#endif
--#ifndef COLLECT_SHARED_FINI_FUNC
--#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \
--  fprintf ((STREAM), "void _GLOBAL__DD() {\n\t%s();\n}\n", (FUNC))
--#endif
--
--#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES
--#define SCAN_LIBRARIES
--#endif
--
--#ifdef USE_COLLECT2
--int do_collecting = 1;
--#else
--int do_collecting = 0;
--#endif
--
--#ifndef COLLECT_PARSE_FLAG
--#define COLLECT_PARSE_FLAG(FLAG)
--#endif
--
--/* Nonzero if we should suppress the automatic demangling of identifiers
--   in linker error messages.  Set from COLLECT_NO_DEMANGLE.  */
--int no_demangle;
--
--/* Linked lists of constructor and destructor names.  */
--
--struct id
--{
--  struct id *next;
--  int sequence;
--  char name[1];
--};
--
--struct head
--{
--  struct id *first;
--  struct id *last;
--  int number;
--};
--
--/* Enumeration giving which pass this is for scanning the program file.  */
--
--enum pass {
--  PASS_FIRST,				/* without constructors */
--  PASS_OBJ,				/* individual objects */
--  PASS_LIB,			        /* looking for shared libraries */
--  PASS_SECOND				/* with constructors linked in */
--};
--
--int vflag;				/* true if -v */
--static int rflag;			/* true if -r */
--static int strip_flag;			/* true if -s */
--#ifdef COLLECT_EXPORT_LIST
--static int export_flag;                 /* true if -bE */
--static int aix64_flag;			/* true if -b64 */
--static int aixrtl_flag;			/* true if -brtl */
--#endif
--
--int debug;				/* true if -debug */
--
--static int shared_obj;		        /* true if -shared */
--
--static const char *c_file;		/* <xxx>.c for constructor/destructor list.  */
--static const char *o_file;		/* <xxx>.o for constructor/destructor list.  */
--#ifdef COLLECT_EXPORT_LIST
--static const char *export_file;	        /* <xxx>.x for AIX export list.  */
--#endif
--const char *ldout;			/* File for ld errors.  */
--static const char *output_file;		/* Output file for ld.  */
--static const char *nm_file_name;	/* pathname of nm */
--#ifdef LDD_SUFFIX
--static const char *ldd_file_name;	/* pathname of ldd (or equivalent) */
--#endif
--static const char *strip_file_name;		/* pathname of strip */
--const char *c_file_name;	        /* pathname of gcc */
--static char *initname, *fininame;	/* names of init and fini funcs */
--
--static struct head constructors;	/* list of constructors found */
--static struct head destructors;		/* list of destructors found */
--#ifdef COLLECT_EXPORT_LIST
--static struct head exports;		/* list of exported symbols */
--#endif
--static struct head frame_tables;	/* list of frame unwind info tables */
--
--struct obstack temporary_obstack;
--char * temporary_firstobj;
--
--/* Holds the return value of pexecute and fork.  */
--int pid;
--
--/* Structure to hold all the directories in which to search for files to
--   execute.  */
--
--struct prefix_list
--{
--  const char *prefix;         /* String to prepend to the path.  */
--  struct prefix_list *next;   /* Next in linked list.  */
--};
--
--struct path_prefix
--{
--  struct prefix_list *plist;  /* List of prefixes to try */
--  int max_len;                /* Max length of a prefix in PLIST */
--  const char *name;           /* Name of this list (used in config stuff) */
--};
--
--#ifdef COLLECT_EXPORT_LIST
--/* Lists to keep libraries to be scanned for global constructors/destructors.  */
--static struct head libs;                    /* list of libraries */
--static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
--static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
--static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
--					  &libpath_lib_dirs, NULL};
--#endif
--
--static void handler (int);
--static int is_ctor_dtor (const char *);
--static char *find_a_file (struct path_prefix *, const char *);
--static void add_prefix (struct path_prefix *, const char *);
--static void prefix_from_env (const char *, struct path_prefix *);
--static void prefix_from_string (const char *, struct path_prefix *);
--static void do_wait (const char *);
--static void fork_execute (const char *, char **);
--static void maybe_unlink (const char *);
--static void add_to_list (struct head *, const char *);
--static int extract_init_priority (const char *);
--static void sort_ids (struct head *);
--static void write_list (FILE *, const char *, struct id *);
--#ifdef COLLECT_EXPORT_LIST
--static void dump_list (FILE *, const char *, struct id *);
--#endif
--#if 0
--static void dump_prefix_list (FILE *, const char *, struct prefix_list *);
--#endif
--static void write_list_with_asm (FILE *, const char *, struct id *);
--static void write_c_file (FILE *, const char *);
--static void write_c_file_stat (FILE *, const char *);
--#ifndef LD_INIT_SWITCH
--static void write_c_file_glob (FILE *, const char *);
--#endif
--static void scan_prog_file (const char *, enum pass);
--#ifdef SCAN_LIBRARIES
--static void scan_libraries (const char *);
--#endif
--#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
--static int is_in_args (const char *, const char **, const char **);
--#endif
--#ifdef COLLECT_EXPORT_LIST
--#if 0
--static int is_in_list (const char *, struct id *);
--#endif
--static void write_aix_file (FILE *, struct id *);
--static char *resolve_lib_name (const char *);
--#endif
--static char *extract_string (const char **);
--
--#ifndef HAVE_DUP2
--static int
--dup2 (int oldfd, int newfd)
--{
--  int fdtmp[256];
--  int fdx = 0;
--  int fd;
--
--  if (oldfd == newfd)
--    return oldfd;
--  close (newfd);
--  while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
--    fdtmp[fdx++] = fd;
--  while (fdx > 0)
--    close (fdtmp[--fdx]);
--
--  return fd;
--}
--#endif /* ! HAVE_DUP2 */
--
--/* Delete tempfiles and exit function.  */
--
--void
--collect_exit (int status)
--{
--  if (c_file != 0 && c_file[0])
--    maybe_unlink (c_file);
--
--  if (o_file != 0 && o_file[0])
--    maybe_unlink (o_file);
--
--#ifdef COLLECT_EXPORT_LIST
--  if (export_file != 0 && export_file[0])
--    maybe_unlink (export_file);
--#endif
--
--  if (ldout != 0 && ldout[0])
--    {
--      dump_file (ldout);
--      maybe_unlink (ldout);
--    }
--
--  if (status != 0 && output_file != 0 && output_file[0])
--    maybe_unlink (output_file);
--
--  exit (status);
--}
--
--
--/* Notify user of a non-error.  */
--void
--notice (const char *msgid, ...)
--{
--  va_list ap;
--
--  va_start (ap, msgid);
--  vfprintf (stderr, _(msgid), ap);
--  va_end (ap);
--}
--
--/* Die when sys call fails.  */
--
--void
--fatal_perror (const char * msgid, ...)
--{
--  int e = errno;
--  va_list ap;
--
--  va_start (ap, msgid);
--  fprintf (stderr, "collect2: ");
--  vfprintf (stderr, _(msgid), ap);
--  fprintf (stderr, ": %s\n", xstrerror (e));
--  va_end (ap);
--
--  collect_exit (FATAL_EXIT_CODE);
--}
--
--/* Just die.  */
--
--void
--fatal (const char * msgid, ...)
--{
--  va_list ap;
--
--  va_start (ap, msgid);
--  fprintf (stderr, "collect2: ");
--  vfprintf (stderr, _(msgid), ap);
--  fprintf (stderr, "\n");
--  va_end (ap);
--
--  collect_exit (FATAL_EXIT_CODE);
--}
--
--/* Write error message.  */
--
--void
--error (const char * msgid, ...)
--{
--  va_list ap;
--
--  va_start (ap, msgid);
--  fprintf (stderr, "collect2: ");
--  vfprintf (stderr, _(msgid), ap);
--  fprintf (stderr, "\n");
--  va_end(ap);
--}
--
--/* In case obstack is linked in, and abort is defined to fancy_abort,
--   provide a default entry.  */
--
--void
--fancy_abort (void)
--{
--  fatal ("internal error");
--}
--
--static void
--handler (int signo)
--{
--  if (c_file != 0 && c_file[0])
--    maybe_unlink (c_file);
--
--  if (o_file != 0 && o_file[0])
--    maybe_unlink (o_file);
--
--  if (ldout != 0 && ldout[0])
--    maybe_unlink (ldout);
--
--#ifdef COLLECT_EXPORT_LIST
--  if (export_file != 0 && export_file[0])
--    maybe_unlink (export_file);
--#endif
--
--  signal (signo, SIG_DFL);
--  kill (getpid (), signo);
--}
--
--
--int
--file_exists (const char *name)
--{
--  return access (name, R_OK) == 0;
--}
--
--/* Parse a reasonable subset of shell quoting syntax.  */
--
--static char *
--extract_string (const char **pp)
--{
--  const char *p = *pp;
--  int backquote = 0;
--  int inside = 0;
--
--  for (;;)
--    {
--      char c = *p;
--      if (c == '\0')
--	break;
--      ++p;
--      if (backquote)
--	obstack_1grow (&temporary_obstack, c);
--      else if (! inside && c == ' ')
--	break;
--      else if (! inside && c == '\\')
--	backquote = 1;
--      else if (c == '\'')
--	inside = !inside;
--      else
--	obstack_1grow (&temporary_obstack, c);
--    }
--
--  obstack_1grow (&temporary_obstack, '\0');
--  *pp = p;
--  return obstack_finish (&temporary_obstack);
--}
--
--void
--dump_file (const char *name)
--{
--  FILE *stream = fopen (name, "r");
--
--  if (stream == 0)
--    return;
--  while (1)
--    {
--      int c;
--      while (c = getc (stream),
--	     c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
--	obstack_1grow (&temporary_obstack, c);
--      if (obstack_object_size (&temporary_obstack) > 0)
--	{
--	  const char *word, *p;
--	  char *result;
--	  obstack_1grow (&temporary_obstack, '\0');
--	  word = obstack_finish (&temporary_obstack);
--
--	  if (*word == '.')
--	    ++word, putc ('.', stderr);
--	  p = word;
--	  if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
--	    p += strlen (USER_LABEL_PREFIX);
--
--	  if (no_demangle)
--	    result = 0;
--	  else
--	    result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
--
--	  if (result)
--	    {
--	      int diff;
--	      fputs (result, stderr);
--
--	      diff = strlen (word) - strlen (result);
--	      while (diff > 0 && c == ' ')
--		--diff, putc (' ', stderr);
--	      while (diff < 0 && c == ' ')
--		++diff, c = getc (stream);
--
--	      free (result);
--	    }
--	  else
--	    fputs (word, stderr);
--
--	  fflush (stderr);
--	  obstack_free (&temporary_obstack, temporary_firstobj);
--	}
--      if (c == EOF)
--	break;
--      putc (c, stderr);
--    }
--  fclose (stream);
--}
--
--/* Decide whether the given symbol is: a constructor (1), a destructor
--   (2), a routine in a shared object that calls all the constructors
--   (3) or destructors (4), a DWARF exception-handling table (5), or
--   nothing special (0).  */
--
--static int
--is_ctor_dtor (const char *s)
--{
--  struct names { const char *const name; const int len; const int ret;
--    const int two_underscores; };
--
--  const struct names *p;
--  int ch;
--  const char *orig_s = s;
--
--  static const struct names special[] = {
--#ifndef NO_DOLLAR_IN_LABEL
--    { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
--    { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
--#else
--#ifndef NO_DOT_IN_LABEL
--    { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
--    { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
--#endif /* NO_DOT_IN_LABEL */
--#endif /* NO_DOLLAR_IN_LABEL */
--    { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
--    { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
--    { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
--    { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
--    { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
--    { NULL, 0, 0, 0 }
--  };
--
--  while ((ch = *s) == '_')
--    ++s;
--
--  if (s == orig_s)
--    return 0;
--
--  for (p = &special[0]; p->len > 0; p++)
--    {
--      if (ch == p->name[0]
--	  && (!p->two_underscores || ((s - orig_s) >= 2))
--	  && strncmp(s, p->name, p->len) == 0)
--	{
--	  return p->ret;
--	}
--    }
--  return 0;
--}
--
--/* We maintain two prefix lists: one from COMPILER_PATH environment variable
--   and one from the PATH variable.  */
--
--static struct path_prefix cpath, path;
--
--#ifdef CROSS_COMPILE
--/* This is the name of the target machine.  We use it to form the name
--   of the files to execute.  */
--
--static const char *const target_machine = TARGET_MACHINE;
--#endif
--
--/* Search for NAME using prefix list PPREFIX.  We only look for executable
--   files.
--
--   Return 0 if not found, otherwise return its name, allocated with malloc.  */
--
--static char *
--find_a_file (struct path_prefix *pprefix, const char *name)
--{
--  char *temp;
--  struct prefix_list *pl;
--  int len = pprefix->max_len + strlen (name) + 1;
--
--  if (debug)
--    fprintf (stderr, "Looking for '%s'\n", name);
--
--#ifdef HOST_EXECUTABLE_SUFFIX
--  len += strlen (HOST_EXECUTABLE_SUFFIX);
--#endif
--
--  temp = xmalloc (len);
--
--  /* Determine the filename to execute (special case for absolute paths).  */
--
--  if (*name == '/'
--#ifdef HAVE_DOS_BASED_FILE_SYSTEM
--      || (*name && name[1] == ':')
--#endif
--      )
--    {
--      if (access (name, X_OK) == 0)
--	{
--	  strcpy (temp, name);
--
--	  if (debug)
--	    fprintf (stderr, "  - found: absolute path\n");
--
--	  return temp;
--	}
--
--#ifdef HOST_EXECUTABLE_SUFFIX
--	/* Some systems have a suffix for executable files.
--	   So try appending that.  */
--      strcpy (temp, name);
--	strcat (temp, HOST_EXECUTABLE_SUFFIX);
--
--	if (access (temp, X_OK) == 0)
--	  return temp;
--#endif
--
--      if (debug)
--	fprintf (stderr, "  - failed to locate using absolute path\n");
--    }
--  else
--    for (pl = pprefix->plist; pl; pl = pl->next)
--      {
--	struct stat st;
--
--	strcpy (temp, pl->prefix);
--	strcat (temp, name);
--
--	if (stat (temp, &st) >= 0
--	    && ! S_ISDIR (st.st_mode)
--	    && access (temp, X_OK) == 0)
--	  return temp;
--
--#ifdef HOST_EXECUTABLE_SUFFIX
--	/* Some systems have a suffix for executable files.
--	   So try appending that.  */
--	strcat (temp, HOST_EXECUTABLE_SUFFIX);
--
--	if (stat (temp, &st) >= 0
--	    && ! S_ISDIR (st.st_mode)
--	    && access (temp, X_OK) == 0)
--	  return temp;
--#endif
--      }
--
--  if (debug && pprefix->plist == NULL)
--    fprintf (stderr, "  - failed: no entries in prefix list\n");
--
--  free (temp);
--  return 0;
--}
--
--/* Add an entry for PREFIX to prefix list PPREFIX.  */
--
--static void
--add_prefix (struct path_prefix *pprefix, const char *prefix)
--{
--  struct prefix_list *pl, **prev;
--  int len;
--
--  if (pprefix->plist)
--    {
--      for (pl = pprefix->plist; pl->next; pl = pl->next)
--	;
--      prev = &pl->next;
--    }
--  else
--    prev = &pprefix->plist;
--
--  /* Keep track of the longest prefix.  */
--
--  len = strlen (prefix);
--  if (len > pprefix->max_len)
--    pprefix->max_len = len;
--
--  pl = xmalloc (sizeof (struct prefix_list));
--  pl->prefix = xstrdup (prefix);
--
--  if (*prev)
--    pl->next = *prev;
--  else
--    pl->next = (struct prefix_list *) 0;
--  *prev = pl;
--}
--
--/* Take the value of the environment variable ENV, break it into a path, and
--   add of the entries to PPREFIX.  */
--
--static void
--prefix_from_env (const char *env, struct path_prefix *pprefix)
--{
--  const char *p;
--  GET_ENVIRONMENT (p, env);
--
--  if (p)
--    prefix_from_string (p, pprefix);
--}
--
--static void
--prefix_from_string (const char *p, struct path_prefix *pprefix)
--{
--  const char *startp, *endp;
--  char *nstore = xmalloc (strlen (p) + 3);
--
--  if (debug)
--    fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
--
--  startp = endp = p;
--  while (1)
--    {
--      if (*endp == PATH_SEPARATOR || *endp == 0)
--	{
--	  strncpy (nstore, startp, endp-startp);
--	  if (endp == startp)
--	    {
--	      strcpy (nstore, "./");
--	    }
--	  else if (! IS_DIR_SEPARATOR (endp[-1]))
--	    {
--	      nstore[endp-startp] = DIR_SEPARATOR;
--	      nstore[endp-startp+1] = 0;
--	    }
--	  else
--	    nstore[endp-startp] = 0;
--
--	  if (debug)
--	    fprintf (stderr, "  - add prefix: %s\n", nstore);
--
--	  add_prefix (pprefix, nstore);
--	  if (*endp == 0)
--	    break;
--	  endp = startp = endp + 1;
--	}
--      else
--	endp++;
--    }
--}
--
--/* Main program.  */
--
--int
--main (int argc, char **argv)
--{
--  static const char *const ld_suffix	= "ld";
--  static const char *const real_ld_suffix = "real-ld";
--  static const char *const collect_ld_suffix = "collect-ld";
--  static const char *const nm_suffix	= "nm";
--  static const char *const gnm_suffix	= "gnm";
--#ifdef LDD_SUFFIX
--  static const char *const ldd_suffix	= LDD_SUFFIX;
--#endif
--  static const char *const strip_suffix = "strip";
--  static const char *const gstrip_suffix = "gstrip";
--
--#ifdef CROSS_COMPILE
--  /* If we look for a program in the compiler directories, we just use
--     the short name, since these directories are already system-specific.
--     But it we look for a program in the system directories, we need to
--     qualify the program name with the target machine.  */
--
--  const char *const full_ld_suffix =
--    concat(target_machine, "-", ld_suffix, NULL);
--  const char *const full_nm_suffix =
--    concat (target_machine, "-", nm_suffix, NULL);
--  const char *const full_gnm_suffix =
--    concat (target_machine, "-", gnm_suffix, NULL);
--#ifdef LDD_SUFFIX
--  const char *const full_ldd_suffix =
--    concat (target_machine, "-", ldd_suffix, NULL);
--#endif
--  const char *const full_strip_suffix =
--    concat (target_machine, "-", strip_suffix, NULL);
--  const char *const full_gstrip_suffix =
--    concat (target_machine, "-", gstrip_suffix, NULL);
--#else
--  const char *const full_ld_suffix	= ld_suffix;
--  const char *const full_nm_suffix	= nm_suffix;
--  const char *const full_gnm_suffix	= gnm_suffix;
--#ifdef LDD_SUFFIX
--  const char *const full_ldd_suffix	= ldd_suffix;
--#endif
--  const char *const full_strip_suffix	= strip_suffix;
--  const char *const full_gstrip_suffix	= gstrip_suffix;
--#endif /* CROSS_COMPILE */
--
--  const char *arg;
--  FILE *outf;
--#ifdef COLLECT_EXPORT_LIST
--  FILE *exportf;
--#endif
--  const char *ld_file_name;
--  const char *p;
--  char **c_argv;
--  const char **c_ptr;
--  char **ld1_argv;
--  const char **ld1;
--  char **ld2_argv;
--  const char **ld2;
--  char **object_lst;
--  const char **object;
--  int first_file;
--  int num_c_args	= argc+9;
--
--  no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
--
--  /* Suppress demangling by the real linker, which may be broken.  */
--  putenv (xstrdup ("COLLECT_NO_DEMANGLE="));
--
--#if defined (COLLECT2_HOST_INITIALIZATION)
--  /* Perform system dependent initialization, if necessary.  */
--  COLLECT2_HOST_INITIALIZATION;
--#endif
--
--#ifdef SIGCHLD
--  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
--     receive the signal.  A different setting is inheritable */
--  signal (SIGCHLD, SIG_DFL);
--#endif
--
--  gcc_init_libintl ();
--
--  /* Do not invoke xcalloc before this point, since locale needs to be
--     set first, in case a diagnostic is issued.  */
--
--  ld1 = (const char **)(ld1_argv = xcalloc(sizeof (char *), argc+3));
--  ld2 = (const char **)(ld2_argv = xcalloc(sizeof (char *), argc+10));
--  object = (const char **)(object_lst = xcalloc(sizeof (char *), argc));
--
--#ifdef DEBUG
--  debug = 1;
--#endif
--
--  /* Parse command line early for instances of -debug.  This allows
--     the debug flag to be set before functions like find_a_file()
--     are called.  */
--  {
--    int i;
--
--    for (i = 1; argv[i] != NULL; i ++)
--      {
--	if (! strcmp (argv[i], "-debug"))
--	  debug = 1;
--	COLLECT_PARSE_FLAG (argv[i]);
--      }
--    vflag = debug;
--  }
--
--#ifndef DEFAULT_A_OUT_NAME
--  output_file = "a.out";
--#else
--  output_file = DEFAULT_A_OUT_NAME;
--#endif
--
--  obstack_begin (&temporary_obstack, 0);
--  temporary_firstobj = obstack_alloc (&temporary_obstack, 0);
--
--  current_demangling_style = auto_demangling;
--  p = getenv ("COLLECT_GCC_OPTIONS");
--  while (p && *p)
--    {
--      const char *q = extract_string (&p);
--      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
--	num_c_args++;
--    }
--  obstack_free (&temporary_obstack, temporary_firstobj);
--
--  /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
--     -fno-exceptions -w */
--  num_c_args += 5;
--
--  c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
--
--  if (argc < 2)
--    fatal ("no arguments");
--
--#ifdef SIGQUIT
--  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
--    signal (SIGQUIT, handler);
--#endif
--  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
--    signal (SIGINT, handler);
--#ifdef SIGALRM
--  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
--    signal (SIGALRM, handler);
--#endif
--#ifdef SIGHUP
--  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
--    signal (SIGHUP, handler);
--#endif
--  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
--    signal (SIGSEGV, handler);
--#ifdef SIGBUS
--  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
--    signal (SIGBUS, handler);
--#endif
--
--  /* Extract COMPILER_PATH and PATH into our prefix list.  */
--  prefix_from_env ("COMPILER_PATH", &cpath);
--  prefix_from_env ("PATH", &path);
--
--  /* Try to discover a valid linker/nm/strip to use.  */
--
--  /* Maybe we know the right file to use (if not cross).  */
--  ld_file_name = 0;
--#ifdef DEFAULT_LINKER
--  if (access (DEFAULT_LINKER, X_OK) == 0)
--    ld_file_name = DEFAULT_LINKER;
--  if (ld_file_name == 0)
--#endif
--#ifdef REAL_LD_FILE_NAME
--  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
--  if (ld_file_name == 0)
--#endif
--  /* Search the (target-specific) compiler dirs for ld'.  */
--  ld_file_name = find_a_file (&cpath, real_ld_suffix);
--  /* Likewise for `collect-ld'.  */
--  if (ld_file_name == 0)
--    ld_file_name = find_a_file (&cpath, collect_ld_suffix);
--  /* Search the compiler directories for `ld'.  We have protection against
--     recursive calls in find_a_file.  */
--  if (ld_file_name == 0)
--    ld_file_name = find_a_file (&cpath, ld_suffix);
--  /* Search the ordinary system bin directories
--     for `ld' (if native linking) or `TARGET-ld' (if cross).  */
--  if (ld_file_name == 0)
--    ld_file_name = find_a_file (&path, full_ld_suffix);
--
--#ifdef REAL_NM_FILE_NAME
--  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
--  if (nm_file_name == 0)
--#endif
--  nm_file_name = find_a_file (&cpath, gnm_suffix);
--  if (nm_file_name == 0)
--    nm_file_name = find_a_file (&path, full_gnm_suffix);
--  if (nm_file_name == 0)
--    nm_file_name = find_a_file (&cpath, nm_suffix);
--  if (nm_file_name == 0)
--    nm_file_name = find_a_file (&path, full_nm_suffix);
--
--#ifdef LDD_SUFFIX
--  ldd_file_name = find_a_file (&cpath, ldd_suffix);
--  if (ldd_file_name == 0)
--    ldd_file_name = find_a_file (&path, full_ldd_suffix);
--#endif
--
--#ifdef REAL_STRIP_FILE_NAME
--  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
--  if (strip_file_name == 0)
--#endif
--  strip_file_name = find_a_file (&cpath, gstrip_suffix);
--  if (strip_file_name == 0)
--    strip_file_name = find_a_file (&path, full_gstrip_suffix);
--  if (strip_file_name == 0)
--    strip_file_name = find_a_file (&cpath, strip_suffix);
--  if (strip_file_name == 0)
--    strip_file_name = find_a_file (&path, full_strip_suffix);
--
--  /* Determine the full path name of the C compiler to use.  */
--  c_file_name = getenv ("COLLECT_GCC");
--  if (c_file_name == 0)
--    {
--#ifdef CROSS_COMPILE
--      c_file_name = concat (target_machine, "-gcc", NULL);
--#else
--      c_file_name = "gcc";
--#endif
--    }
--
--  p = find_a_file (&cpath, c_file_name);
--
--  /* Here it should be safe to use the system search path since we should have
--     already qualified the name of the compiler when it is needed.  */
--  if (p == 0)
--    p = find_a_file (&path, c_file_name);
--
--  if (p)
--    c_file_name = p;
--
--  *ld1++ = *ld2++ = ld_file_name;
--
--  /* Make temp file names.  */
--  c_file = make_temp_file (".c");
--  o_file = make_temp_file (".o");
--#ifdef COLLECT_EXPORT_LIST
--  export_file = make_temp_file (".x");
--#endif
--  ldout = make_temp_file (".ld");
--  *c_ptr++ = c_file_name;
--  *c_ptr++ = "-x";
--  *c_ptr++ = "c";
--  *c_ptr++ = "-c";
--  *c_ptr++ = "-o";
--  *c_ptr++ = o_file;
--
--#ifdef COLLECT_EXPORT_LIST
--  /* Generate a list of directories from LIBPATH.  */
--  prefix_from_env ("LIBPATH", &libpath_lib_dirs);
--  /* Add to this list also two standard directories where
--     AIX loader always searches for libraries.  */
--  add_prefix (&libpath_lib_dirs, "/lib");
--  add_prefix (&libpath_lib_dirs, "/usr/lib");
--#endif
--
--  /* Get any options that the upper GCC wants to pass to the sub-GCC.
--
--     AIX support needs to know if -shared has been specified before
--     parsing commandline arguments.  */
--
--  p = getenv ("COLLECT_GCC_OPTIONS");
--  while (p && *p)
--    {
--      const char *q = extract_string (&p);
--      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))
--	*c_ptr++ = xstrdup (q);
--      if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0)
--	*c_ptr++ = xstrdup (q);
--      if (strcmp (q, "-shared") == 0)
--	shared_obj = 1;
--      if (*q == '-' && q[1] == 'B')
--	{
--	  *c_ptr++ = xstrdup (q);
--	  if (q[2] == 0)
--	    {
--	      q = extract_string (&p);
--	      *c_ptr++ = xstrdup (q);
--	    }
--	}
--    }
--  obstack_free (&temporary_obstack, temporary_firstobj);
--  *c_ptr++ = "-fno-profile-arcs";
--  *c_ptr++ = "-fno-test-coverage";
--  *c_ptr++ = "-fno-branch-probabilities";
--  *c_ptr++ = "-fno-exceptions";
--  *c_ptr++ = "-w";
--
--  /* !!! When GCC calls collect2,
--     it does not know whether it is calling collect2 or ld.
--     So collect2 cannot meaningfully understand any options
--     except those ld understands.
--     If you propose to make GCC pass some other option,
--     just imagine what will happen if ld is really ld!!!  */
--
--  /* Parse arguments.  Remember output file spec, pass the rest to ld.  */
--  /* After the first file, put in the c++ rt0.  */
--
--  first_file = 1;
--  while ((arg = *++argv) != (char *) 0)
--    {
--      *ld1++ = *ld2++ = arg;
--
--      if (arg[0] == '-')
--	{
--	  switch (arg[1])
--	    {
--#ifdef COLLECT_EXPORT_LIST
--	    /* We want to disable automatic exports on AIX when user
--	       explicitly puts an export list in command line */
--	    case 'b':
--	      if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
--                export_flag = 1;
--	      else if (arg[2] == '6' && arg[3] == '4')
--		aix64_flag = 1;
--	      else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
--		aixrtl_flag = 1;
--	      break;
--#endif
--
--	    case 'd':
--	      if (!strcmp (arg, "-debug"))
--		{
--		  /* Already parsed.  */
--		  ld1--;
--		  ld2--;
--		}
--	      break;
--
--	    case 'l':
--	      if (first_file)
--		{
--		  /* place o_file BEFORE this argument! */
--		  first_file = 0;
--		  ld2--;
--		  *ld2++ = o_file;
--		  *ld2++ = arg;
--		}
--#ifdef COLLECT_EXPORT_LIST
--	      {
--	        /* Resolving full library name.  */
--		const char *s = resolve_lib_name (arg+2);
--
--		/* Saving a full library name.  */
--		add_to_list (&libs, s);
--	      }
--#endif
--	      break;
--
--#ifdef COLLECT_EXPORT_LIST
--	    /* Saving directories where to search for libraries.  */
--	    case 'L':
--	      add_prefix (&cmdline_lib_dirs, arg+2);
--	      break;
--#else
--#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
--	    case 'L':
--	      if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
--		--ld1;
--	      break;
--#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
--#endif
--
--	    case 'o':
--	      if (arg[2] == '\0')
--		output_file = *ld1++ = *ld2++ = *++argv;
--	      else if (1
--#ifdef SWITCHES_NEED_SPACES
--		       && ! strchr (SWITCHES_NEED_SPACES, arg[1])
--#endif
--		       )
--
--		output_file = &arg[2];
--	      break;
--
--	    case 'r':
--	      if (arg[2] == '\0')
--		rflag = 1;
--	      break;
--
--	    case 's':
--	      if (arg[2] == '\0' && do_collecting)
--		{
--		  /* We must strip after the nm run, otherwise C++ linking
--		     will not work.  Thus we strip in the second ld run, or
--		     else with strip if there is no second ld run.  */
--		  strip_flag = 1;
--		  ld1--;
--		}
--	      break;
--
--	    case 'v':
--	      if (arg[2] == '\0')
--		vflag = 1;
--	      break;
--	    }
--	}
--      else if ((p = strrchr (arg, '.')) != (char *) 0
--	       && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0
--		   || strcmp (p, ".so") == 0 || strcmp (p, ".lo") == 0
--		   || strcmp (p, ".obj") == 0))
--	{
--	  if (first_file)
--	    {
--	      first_file = 0;
--	      if (p[1] == 'o')
--		*ld2++ = o_file;
--	      else
--		{
--		  /* place o_file BEFORE this argument! */
--		  ld2--;
--		  *ld2++ = o_file;
--		  *ld2++ = arg;
--		}
--	    }
--	  if (p[1] == 'o' || p[1] == 'l')
--	    *object++ = arg;
--#ifdef COLLECT_EXPORT_LIST
--	  /* libraries can be specified directly, i.e. without -l flag.  */
--	  else
--	    {
--	      /* Saving a full library name.  */
--              add_to_list (&libs, arg);
--            }
--#endif
--	}
--    }
--
--#ifdef COLLECT_EXPORT_LIST
--  /* This is added only for debugging purposes.  */
--  if (debug)
--    {
--      fprintf (stderr, "List of libraries:\n");
--      dump_list (stderr, "\t", libs.first);
--    }
--
--  /* The AIX linker will discard static constructors in object files if
--     nothing else in the file is referenced, so look at them first.  */
--  {
--      const char **export_object_lst = (const char **)object_lst;
--
--      while (export_object_lst < object)
--	scan_prog_file (*export_object_lst++, PASS_OBJ);
--  }
--  {
--    struct id *list = libs.first;
--
--    for (; list; list = list->next)
--      scan_prog_file (list->name, PASS_FIRST);
--  }
--
--  if (exports.first)
--    {
--      char *buf = concat ("-bE:", export_file, NULL);
--
--      *ld1++ = buf;
--      *ld2++ = buf;
--
--      exportf = fopen (export_file, "w");
--      if (exportf == (FILE *) 0)
--	fatal_perror ("fopen %s", export_file);
--      write_aix_file (exportf, exports.first);
--      if (fclose (exportf))
--	fatal_perror ("fclose %s", export_file);
--    }
--#endif
--
--  *c_ptr++ = c_file;
--  *c_ptr = *ld1 = *object = (char *) 0;
--
--  if (vflag)
--    {
--      notice ("collect2 version %s", version_string);
--#ifdef TARGET_VERSION
--      TARGET_VERSION;
--#endif
--      fprintf (stderr, "\n");
--    }
--
--  if (debug)
--    {
--      const char *ptr;
--      fprintf (stderr, "ld_file_name        = %s\n",
--	       (ld_file_name ? ld_file_name : "not found"));
--      fprintf (stderr, "c_file_name         = %s\n",
--	       (c_file_name ? c_file_name : "not found"));
--      fprintf (stderr, "nm_file_name        = %s\n",
--	       (nm_file_name ? nm_file_name : "not found"));
--#ifdef LDD_SUFFIX
--      fprintf (stderr, "ldd_file_name       = %s\n",
--	       (ldd_file_name ? ldd_file_name : "not found"));
--#endif
--      fprintf (stderr, "strip_file_name     = %s\n",
--	       (strip_file_name ? strip_file_name : "not found"));
--      fprintf (stderr, "c_file              = %s\n",
--	       (c_file ? c_file : "not found"));
--      fprintf (stderr, "o_file              = %s\n",
--	       (o_file ? o_file : "not found"));
--
--      ptr = getenv ("COLLECT_GCC_OPTIONS");
--      if (ptr)
--	fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);
--
--      ptr = getenv ("COLLECT_GCC");
--      if (ptr)
--	fprintf (stderr, "COLLECT_GCC         = %s\n", ptr);
--
--      ptr = getenv ("COMPILER_PATH");
--      if (ptr)
--	fprintf (stderr, "COMPILER_PATH       = %s\n", ptr);
--
--      ptr = getenv (LIBRARY_PATH_ENV);
--      if (ptr)
--	fprintf (stderr, "%-20s= %s\n", LIBRARY_PATH_ENV, ptr);
--
--      fprintf (stderr, "\n");
--    }
--
--  /* Load the program, searching all libraries and attempting to provide
--     undefined symbols from repository information.  */
--
--  /* On AIX we do this later.  */
--#ifndef COLLECT_EXPORT_LIST
--  do_tlink (ld1_argv, object_lst);
--#endif
--
--  /* If -r or they will be run via some other method, do not build the
--     constructor or destructor list, just return now.  */
--  if (rflag
--#ifndef COLLECT_EXPORT_LIST
--      || ! do_collecting
--#endif
--      )
--    {
--#ifdef COLLECT_EXPORT_LIST
--      /* Do the link we avoided above if we are exiting.  */
--      do_tlink (ld1_argv, object_lst);
--
--      /* But make sure we delete the export file we may have created.  */
--      if (export_file != 0 && export_file[0])
--	maybe_unlink (export_file);
--#endif
--      maybe_unlink (c_file);
--      maybe_unlink (o_file);
--      return 0;
--    }
--
--  /* Examine the namelist with nm and search it for static constructors
--     and destructors to call.
--     Write the constructor and destructor tables to a .s file and reload.  */
--
--  /* On AIX we already scanned for global constructors/destructors.  */
--#ifndef COLLECT_EXPORT_LIST
--  scan_prog_file (output_file, PASS_FIRST);
--#endif
--
--#ifdef SCAN_LIBRARIES
--  scan_libraries (output_file);
--#endif
--
--  if (debug)
--    {
--      notice ("%d constructor(s) found\n", constructors.number);
--      notice ("%d destructor(s)  found\n", destructors.number);
--      notice ("%d frame table(s) found\n", frame_tables.number);
--    }
--
--  if (constructors.number == 0 && destructors.number == 0
--      && frame_tables.number == 0
--#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST)
--      /* If we will be running these functions ourselves, we want to emit
--	 stubs into the shared library so that we do not have to relink
--	 dependent programs when we add static objects.  */
--      && ! shared_obj
--#endif
--      )
--    {
--#ifdef COLLECT_EXPORT_LIST
--      /* Do tlink without additional code generation.  */
--      do_tlink (ld1_argv, object_lst);
--#endif
--      /* Strip now if it was requested on the command line.  */
--      if (strip_flag)
--	{
--	  char **real_strip_argv = xcalloc (sizeof (char *), 3);
--	  const char ** strip_argv = (const char **) real_strip_argv;
--
--	  strip_argv[0] = strip_file_name;
--	  strip_argv[1] = output_file;
--	  strip_argv[2] = (char *) 0;
--	  fork_execute ("strip", real_strip_argv);
--	}
--
--#ifdef COLLECT_EXPORT_LIST
--      maybe_unlink (export_file);
--#endif
--      maybe_unlink (c_file);
--      maybe_unlink (o_file);
--      return 0;
--    }
--
--  /* Sort ctor and dtor lists by priority.  */
--  sort_ids (&constructors);
--  sort_ids (&destructors);
--
--  maybe_unlink(output_file);
--  outf = fopen (c_file, "w");
--  if (outf == (FILE *) 0)
--    fatal_perror ("fopen %s", c_file);
--
--  write_c_file (outf, c_file);
--
--  if (fclose (outf))
--    fatal_perror ("fclose %s", c_file);
--
--  /* Tell the linker that we have initializer and finalizer functions.  */
--#ifdef LD_INIT_SWITCH
--#ifdef COLLECT_EXPORT_LIST
--  *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL);
--#else
--  *ld2++ = LD_INIT_SWITCH;
--  *ld2++ = initname;
--  *ld2++ = LD_FINI_SWITCH;
--  *ld2++ = fininame;
--#endif
--#endif
--
--#ifdef COLLECT_EXPORT_LIST
--  if (shared_obj)
--    {
--      /* If we did not add export flag to link arguments before, add it to
--	 second link phase now.  No new exports should have been added.  */
--      if (! exports.first)
--	*ld2++ = concat ("-bE:", export_file, NULL);
--
--#ifndef LD_INIT_SWITCH
--      add_to_list (&exports, initname);
--      add_to_list (&exports, fininame);
--      add_to_list (&exports, "_GLOBAL__DI");
--      add_to_list (&exports, "_GLOBAL__DD");
--#endif
--      exportf = fopen (export_file, "w");
--      if (exportf == (FILE *) 0)
--	fatal_perror ("fopen %s", export_file);
--      write_aix_file (exportf, exports.first);
--      if (fclose (exportf))
--	fatal_perror ("fclose %s", export_file);
--    }
--#endif
--
--  /* End of arguments to second link phase.  */
--  *ld2 = (char*) 0;
--
--  if (debug)
--    {
--      fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",
--	       output_file, c_file);
--      write_c_file (stderr, "stderr");
--      fprintf (stderr, "========== end of c_file\n\n");
--#ifdef COLLECT_EXPORT_LIST
--      fprintf (stderr, "\n========== export_file = %s\n", export_file);
--      write_aix_file (stderr, exports.first);
--      fprintf (stderr, "========== end of export_file\n\n");
--#endif
--    }
--
--  /* Assemble the constructor and destructor tables.
--     Link the tables in with the rest of the program.  */
--
--  fork_execute ("gcc",  c_argv);
--#ifdef COLLECT_EXPORT_LIST
--  /* On AIX we must call tlink because of possible templates resolution.  */
--  do_tlink (ld2_argv, object_lst);
--#else
--  /* Otherwise, simply call ld because tlink is already done.  */
--  fork_execute ("ld", ld2_argv);
--
--  /* Let scan_prog_file do any final mods (OSF/rose needs this for
--     constructors/destructors in shared libraries.  */
--  scan_prog_file (output_file, PASS_SECOND);
--#endif
--
--  maybe_unlink (c_file);
--  maybe_unlink (o_file);
--
--#ifdef COLLECT_EXPORT_LIST
--  maybe_unlink (export_file);
--#endif
--
--  return 0;
--}
--
--
--/* Wait for a process to finish, and exit if a nonzero status is found.  */
--
--int
--collect_wait (const char *prog)
--{
--  int status;
--
--  pwait (pid, &status, 0);
--  if (status)
--    {
--      if (WIFSIGNALED (status))
--	{
--	  int sig = WTERMSIG (status);
--	  error ("%s terminated with signal %d [%s]%s",
--		 prog, sig, strsignal(sig),
--		 WCOREDUMP(status) ? ", core dumped" : "");
--	  collect_exit (FATAL_EXIT_CODE);
--	}
--
--      if (WIFEXITED (status))
--	return WEXITSTATUS (status);
--    }
--  return 0;
--}
--
--static void
--do_wait (const char *prog)
--{
--  int ret = collect_wait (prog);
--  if (ret != 0)
--    {
--      error ("%s returned %d exit status", prog, ret);
--      collect_exit (ret);
--    }
--}
--
--
--/* Execute a program, and wait for the reply.  */
--
--void
--collect_execute (const char *prog, char **argv, const char *redir)
--{
--  char *errmsg_fmt;
--  char *errmsg_arg;
--  int redir_handle = -1;
--  int stdout_save = -1;
--  int stderr_save = -1;
--
--  if (vflag || debug)
--    {
--      char **p_argv;
--      const char *str;
--
--      if (argv[0])
--	fprintf (stderr, "%s", argv[0]);
--      else
--	notice ("[cannot find %s]", prog);
--
--      for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
--	fprintf (stderr, " %s", str);
--
--      fprintf (stderr, "\n");
--    }
--
--  fflush (stdout);
--  fflush (stderr);
--
--  /* If we cannot find a program we need, complain error.  Do this here
--     since we might not end up needing something that we could not find.  */
--
--  if (argv[0] == 0)
--    fatal ("cannot find `%s'", prog);
--
--  if (redir)
--    {
--      /* Open response file.  */
--      redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT);
--
--      /* Duplicate the stdout and stderr file handles
--	 so they can be restored later.  */
--      stdout_save = dup (STDOUT_FILENO);
--      if (stdout_save == -1)
--	fatal_perror ("redirecting stdout: %s", redir);
--      stderr_save = dup (STDERR_FILENO);
--      if (stderr_save == -1)
--	fatal_perror ("redirecting stdout: %s", redir);
--
--      /* Redirect stdout & stderr to our response file.  */
--      dup2 (redir_handle, STDOUT_FILENO);
--      dup2 (redir_handle, STDERR_FILENO);
--    }
--
--  pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg,
--		  (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
--
--  if (redir)
--    {
--      /* Restore stdout and stderr to their previous settings.  */
--      dup2 (stdout_save, STDOUT_FILENO);
--      dup2 (stderr_save, STDERR_FILENO);
--
--      /* Close response file.  */
--      close (redir_handle);
--    }
--
-- if (pid == -1)
--   fatal_perror (errmsg_fmt, errmsg_arg);
--}
--
--static void
--fork_execute (const char *prog, char **argv)
--{
--  collect_execute (prog, argv, NULL);
--  do_wait (prog);
--}
--
--/* Unlink a file unless we are debugging.  */
--
--static void
--maybe_unlink (const char *file)
--{
--  if (!debug)
--    unlink (file);
--  else
--    notice ("[Leaving %s]\n", file);
--}
--
--
--static long sequence_number = 0;
--
--/* Add a name to a linked list.  */
--
--static void
--add_to_list (struct head *head_ptr, const char *name)
--{
--  struct id *newid = xcalloc (sizeof (struct id) + strlen (name), 1);
--  struct id *p;
--  strcpy (newid->name, name);
--
--  if (head_ptr->first)
--    head_ptr->last->next = newid;
--  else
--    head_ptr->first = newid;
--
--  /* Check for duplicate symbols.  */
--  for (p = head_ptr->first;
--       strcmp (name, p->name) != 0;
--       p = p->next)
--    ;
--  if (p != newid)
--    {
--      head_ptr->last->next = 0;
--      free (newid);
--      return;
--    }
--
--  newid->sequence = ++sequence_number;
--  head_ptr->last = newid;
--  head_ptr->number++;
--}
--
--/* Grab the init priority number from an init function name that
--   looks like "_GLOBAL_.I.12345.foo".  */
--
--static int
--extract_init_priority (const char *name)
--{
--  int pos = 0, pri;
--
--  while (name[pos] == '_')
--    ++pos;
--  pos += 10; /* strlen ("GLOBAL__X_") */
--
--  /* Extract init_p number from ctor/dtor name.  */
--  pri = atoi (name + pos);
--  return pri ? pri : DEFAULT_INIT_PRIORITY;
--}
--
--/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order.
--   ctors will be run from right to left, dtors from left to right.  */
--
--static void
--sort_ids (struct head *head_ptr)
--{
--  /* id holds the current element to insert.  id_next holds the next
--     element to insert.  id_ptr iterates through the already sorted elements
--     looking for the place to insert id.  */
--  struct id *id, *id_next, **id_ptr;
--
--  id = head_ptr->first;
--
--  /* We don't have any sorted elements yet.  */
--  head_ptr->first = NULL;
--
--  for (; id; id = id_next)
--    {
--      id_next = id->next;
--      id->sequence = extract_init_priority (id->name);
--
--      for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next))
--	if (*id_ptr == NULL
--	    /* If the sequence numbers are the same, we put the id from the
--	       file later on the command line later in the list.  */
--	    || id->sequence > (*id_ptr)->sequence
--	    /* Hack: do lexical compare, too.
--	    || (id->sequence == (*id_ptr)->sequence
--	        && strcmp (id->name, (*id_ptr)->name) > 0) */
--	    )
--	  {
--	    id->next = *id_ptr;
--	    *id_ptr = id;
--	    break;
--	  }
--    }
--
--  /* Now set the sequence numbers properly so write_c_file works.  */
--  for (id = head_ptr->first; id; id = id->next)
--    id->sequence = ++sequence_number;
--}
--
--/* Write: `prefix', the names on list LIST, `suffix'.  */
--
--static void
--write_list (FILE *stream, const char *prefix, struct id *list)
--{
--  while (list)
--    {
--      fprintf (stream, "%sx%d,\n", prefix, list->sequence);
--      list = list->next;
--    }
--}
--
--#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
--/* Given a STRING, return nonzero if it occurs in the list in range
--   [ARGS_BEGIN,ARGS_END).  */
--
--static int
--is_in_args (const char *string, const char **args_begin,
--	    const char **args_end)
--{
--  const char **args_pointer;
--  for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
--    if (strcmp (string, *args_pointer) == 0)
--      return 1;
--  return 0;
--}
--#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
--
--#ifdef COLLECT_EXPORT_LIST
--/* This function is really used only on AIX, but may be useful.  */
--#if 0
--static int
--is_in_list (const char *prefix, struct id *list)
--{
--  while (list)
--    {
--      if (!strcmp (prefix, list->name)) return 1;
--      list = list->next;
--    }
--    return 0;
--}
--#endif
--#endif /* COLLECT_EXPORT_LIST */
--
--/* Added for debugging purpose.  */
--#ifdef COLLECT_EXPORT_LIST
--static void
--dump_list (FILE *stream, const char *prefix, struct id *list)
--{
--  while (list)
--    {
--      fprintf (stream, "%s%s,\n", prefix, list->name);
--      list = list->next;
--    }
--}
--#endif
--
--#if 0
--static void
--dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
--{
--  while (list)
--    {
--      fprintf (stream, "%s%s,\n", prefix, list->prefix);
--      list = list->next;
--    }
--}
--#endif
--
--static void
--write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
--{
--  while (list)
--    {
--      fprintf (stream, "%sx%d __asm__ (\"%s\");\n",
--	       prefix, list->sequence, list->name);
--      list = list->next;
--    }
--}
--
--/* Write out the constructor and destructor tables statically (for a shared
--   object), along with the functions to execute them.  */
--
--static void
--write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
--{
--  const char *p, *q;
--  char *prefix, *r;
--  int frames = (frame_tables.number > 0);
--
--  /* Figure out name of output_file, stripping off .so version.  */
--  p = strrchr (output_file, '/');
--  if (p == 0)
--    p = output_file;
--  else
--    p++;
--  q = p;
--  while (q)
--    {
--      q = strchr (q,'.');
--      if (q == 0)
--	{
--	  q = p + strlen (p);
--	  break;
--	}
--      else
--	{
--	  if (strncmp (q, ".so", 3) == 0)
--	    {
--	      q += 3;
--	      break;
--	    }
--	  else
--	    q++;
--	}
--    }
--  /* q points to null at end of the string (or . of the .so version) */
--  prefix = xmalloc (q - p + 1);
--  strncpy (prefix, p, q - p);
--  prefix[q - p] = 0;
--  for (r = prefix; *r; r++)
--    if (!ISALNUM ((unsigned char)*r))
--      *r = '_';
--  if (debug)
--    notice ("\nwrite_c_file - output name is %s, prefix is %s\n",
--	    output_file, prefix);
--
--  initname = concat ("_GLOBAL__FI_", prefix, NULL);
--  fininame = concat ("_GLOBAL__FD_", prefix, NULL);
--
--  free (prefix);
--
--  /* Write the tables as C code.  */
--
--  fprintf (stream, "static int count;\n");
--  fprintf (stream, "typedef void entry_pt();\n");
--  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
--
--  if (frames)
--    {
--      write_list_with_asm (stream, "extern void *", frame_tables.first);
--
--      fprintf (stream, "\tstatic void *frame_table[] = {\n");
--      write_list (stream, "\t\t&", frame_tables.first);
--      fprintf (stream, "\t0\n};\n");
--
--      /* This must match what's in frame.h.  */
--      fprintf (stream, "struct object {\n");
--      fprintf (stream, "  void *pc_begin;\n");
--      fprintf (stream, "  void *pc_end;\n");
--      fprintf (stream, "  void *fde_begin;\n");
--      fprintf (stream, "  void *fde_array;\n");
--      fprintf (stream, "  __SIZE_TYPE__ count;\n");
--      fprintf (stream, "  struct object *next;\n");
--      fprintf (stream, "};\n");
--
--      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
--      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
--
--      fprintf (stream, "static void reg_frame () {\n");
--      fprintf (stream, "\tstatic struct object ob;\n");
--      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
--      fprintf (stream, "\t}\n");
--
--      fprintf (stream, "static void dereg_frame () {\n");
--      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
--      fprintf (stream, "\t}\n");
--    }
--
--  fprintf (stream, "void %s() {\n", initname);
--  if (constructors.number > 0 || frames)
--    {
--      fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
--      write_list (stream, "\t\t", constructors.first);
--      if (frames)
--	fprintf (stream, "\treg_frame,\n");
--      fprintf (stream, "\t};\n");
--      fprintf (stream, "\tentry_pt **p;\n");
--      fprintf (stream, "\tif (count++ != 0) return;\n");
--      fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);
--      fprintf (stream, "\twhile (p > ctors) (*--p)();\n");
--    }
--  else
--    fprintf (stream, "\t++count;\n");
--  fprintf (stream, "}\n");
--  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
--  fprintf (stream, "void %s() {\n", fininame);
--  if (destructors.number > 0 || frames)
--    {
--      fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
--      write_list (stream, "\t\t", destructors.first);
--      if (frames)
--	fprintf (stream, "\tdereg_frame,\n");
--      fprintf (stream, "\t};\n");
--      fprintf (stream, "\tentry_pt **p;\n");
--      fprintf (stream, "\tif (--count != 0) return;\n");
--      fprintf (stream, "\tp = dtors;\n");
--      fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",
--	       destructors.number + frames);
--    }
--  fprintf (stream, "}\n");
--
--  if (shared_obj)
--    {
--      COLLECT_SHARED_INIT_FUNC(stream, initname);
--      COLLECT_SHARED_FINI_FUNC(stream, fininame);
--    }
--}
--
--/* Write the constructor/destructor tables.  */
--
--#ifndef LD_INIT_SWITCH
--static void
--write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
--{
--  /* Write the tables as C code.  */
--
--  int frames = (frame_tables.number > 0);
--
--  fprintf (stream, "typedef void entry_pt();\n\n");
--
--  write_list_with_asm (stream, "extern entry_pt ", constructors.first);
--
--  if (frames)
--    {
--      write_list_with_asm (stream, "extern void *", frame_tables.first);
--
--      fprintf (stream, "\tstatic void *frame_table[] = {\n");
--      write_list (stream, "\t\t&", frame_tables.first);
--      fprintf (stream, "\t0\n};\n");
--
--      /* This must match what's in frame.h.  */
--      fprintf (stream, "struct object {\n");
--      fprintf (stream, "  void *pc_begin;\n");
--      fprintf (stream, "  void *pc_end;\n");
--      fprintf (stream, "  void *fde_begin;\n");
--      fprintf (stream, "  void *fde_array;\n");
--      fprintf (stream, "  __SIZE_TYPE__ count;\n");
--      fprintf (stream, "  struct object *next;\n");
--      fprintf (stream, "};\n");
--
--      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");
--      fprintf (stream, "extern void *__deregister_frame_info (void *);\n");
--
--      fprintf (stream, "static void reg_frame () {\n");
--      fprintf (stream, "\tstatic struct object ob;\n");
--      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");
--      fprintf (stream, "\t}\n");
--
--      fprintf (stream, "static void dereg_frame () {\n");
--      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");
--      fprintf (stream, "\t}\n");
--    }
--
--  fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");
--  fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);
--  write_list (stream, "\t", constructors.first);
--  if (frames)
--    fprintf (stream, "\treg_frame,\n");
--  fprintf (stream, "\t0\n};\n\n");
--
--  write_list_with_asm (stream, "extern entry_pt ", destructors.first);
--
--  fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");
--  fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);
--  write_list (stream, "\t", destructors.first);
--  if (frames)
--    fprintf (stream, "\tdereg_frame,\n");
--  fprintf (stream, "\t0\n};\n\n");
--
--  fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);
--  fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
--}
--#endif /* ! LD_INIT_SWITCH */
--
--static void
--write_c_file (FILE *stream, const char *name)
--{
--  fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
--#ifndef LD_INIT_SWITCH
--  if (! shared_obj)
--    write_c_file_glob (stream, name);
--  else
--#endif
--    write_c_file_stat (stream, name);
--  fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");
--}
--
--#ifdef COLLECT_EXPORT_LIST
--static void
--write_aix_file (FILE *stream, struct id *list)
--{
--  for (; list; list = list->next)
--    {
--      fputs (list->name, stream);
--      putc ('\n', stream);
--    }
--}
--#endif
--
--#ifdef OBJECT_FORMAT_NONE
--
--/* Generic version to scan the name list of the loaded program for
--   the symbols g++ uses for static constructors and destructors.
--
--   The constructor table begins at __CTOR_LIST__ and contains a count
--   of the number of pointers (or -1 if the constructors are built in a
--   separate section by the linker), followed by the pointers to the
--   constructor functions, terminated with a null pointer.  The
--   destructor table has the same format, and begins at __DTOR_LIST__.  */
--
--static void
--scan_prog_file (const char *prog_name, enum pass which_pass)
--{
--  void (*int_handler) (int);
--  void (*quit_handler) (int);
--  char *real_nm_argv[4];
--  const char **nm_argv = (const char **) real_nm_argv;
--  int argc = 0;
--  int pipe_fd[2];
--  char *p, buf[1024];
--  FILE *inf;
--
--  if (which_pass == PASS_SECOND)
--    return;
--
--  /* If we do not have an `nm', complain.  */
--  if (nm_file_name == 0)
--    fatal ("cannot find `nm'");
--
--  nm_argv[argc++] = nm_file_name;
--  if (NM_FLAGS[0] != '\0')
--    nm_argv[argc++] = NM_FLAGS;
--
--  nm_argv[argc++] = prog_name;
--  nm_argv[argc++] = (char *) 0;
--
--  if (pipe (pipe_fd) < 0)
--    fatal_perror ("pipe");
--
--  inf = fdopen (pipe_fd[0], "r");
--  if (inf == (FILE *) 0)
--    fatal_perror ("fdopen");
--
--  /* Trace if needed.  */
--  if (vflag)
--    {
--      const char **p_argv;
--      const char *str;
--
--      for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
--	fprintf (stderr, " %s", str);
--
--      fprintf (stderr, "\n");
--    }
--
--  fflush (stdout);
--  fflush (stderr);
--
--  /* Spawn child nm on pipe.  */
--  pid = vfork ();
--  if (pid == -1)
--    fatal_perror (VFORK_STRING);
--
--  if (pid == 0)			/* child context */
--    {
--      /* setup stdout */
--      if (dup2 (pipe_fd[1], 1) < 0)
--	fatal_perror ("dup2 %d 1", pipe_fd[1]);
--
--      if (close (pipe_fd[0]) < 0)
--	fatal_perror ("close %d", pipe_fd[0]);
--
--      if (close (pipe_fd[1]) < 0)
--	fatal_perror ("close %d", pipe_fd[1]);
--
--      execv (nm_file_name, real_nm_argv);
--      fatal_perror ("execv %s", nm_file_name);
--    }
--
--  /* Parent context from here on.  */
--  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
--#ifdef SIGQUIT
--  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
--#endif
--
--  if (close (pipe_fd[1]) < 0)
--    fatal_perror ("close %d", pipe_fd[1]);
--
--  if (debug)
--    fprintf (stderr, "\nnm output with constructors/destructors.\n");
--
--  /* Read each line of nm output.  */
--  while (fgets (buf, sizeof buf, inf) != (char *) 0)
--    {
--      int ch, ch2;
--      char *name, *end;
--
--      /* If it contains a constructor or destructor name, add the name
--	 to the appropriate list.  */
--
--      for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
--	if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
--	  break;
--
--      if (ch != '_')
--	continue;
--
--      name = p;
--      /* Find the end of the symbol name.
--	 Do not include `|', because Encore nm can tack that on the end.  */
--      for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|';
--	   end++)
--	continue;
--
--
--      *end = '\0';
--      switch (is_ctor_dtor (name))
--	{
--	case 1:
--	  if (which_pass != PASS_LIB)
--	    add_to_list (&constructors, name);
--	  break;
--
--	case 2:
--	  if (which_pass != PASS_LIB)
--	    add_to_list (&destructors, name);
--	  break;
--
--	case 3:
--	  if (which_pass != PASS_LIB)
--	    fatal ("init function found in object %s", prog_name);
--#ifndef LD_INIT_SWITCH
--	  add_to_list (&constructors, name);
--#endif
--	  break;
--
--	case 4:
--	  if (which_pass != PASS_LIB)
--	    fatal ("fini function found in object %s", prog_name);
--#ifndef LD_FINI_SWITCH
--	  add_to_list (&destructors, name);
--#endif
--	  break;
--
--	case 5:
--	  if (which_pass != PASS_LIB)
--	    add_to_list (&frame_tables, name);
--	  break;
--
--	default:		/* not a constructor or destructor */
--	  continue;
--	}
--
--      if (debug)
--	fprintf (stderr, "\t%s\n", buf);
--    }
--
--  if (debug)
--    fprintf (stderr, "\n");
--
--  if (fclose (inf) != 0)
--    fatal_perror ("fclose");
--
--  do_wait (nm_file_name);
--
--  signal (SIGINT,  int_handler);
--#ifdef SIGQUIT
--  signal (SIGQUIT, quit_handler);
--#endif
--}
--
--#if SUNOS4_SHARED_LIBRARIES
--
--/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
--   that the output file depends upon and their initialization/finalization
--   routines, if any.  */
--
--#include <a.out.h>
--#include <fcntl.h>
--#include <link.h>
--#include <sys/mman.h>
--#include <sys/param.h>
--#include <unistd.h>
--#include <sys/dir.h>
--
--/* pointers to the object file */
--unsigned object;	/* address of memory mapped file */
--unsigned objsize;	/* size of memory mapped to file */
--char * code;		/* pointer to code segment */
--char * data;		/* pointer to data segment */
--struct nlist *symtab;	/* pointer to symbol table */
--struct link_dynamic *ld;
--struct link_dynamic_2 *ld_2;
--struct head libraries;
--
--/* Map the file indicated by NAME into memory and store its address.  */
--
--static void
--mapfile (const char *name)
--{
--  int fp;
--  struct stat s;
--  if ((fp = open (name, O_RDONLY)) == -1)
--    fatal ("unable to open file '%s'", name);
--  if (fstat (fp, &s) == -1)
--    fatal ("unable to stat file '%s'", name);
--
--  objsize = s.st_size;
--  object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
--			    fp, 0);
--  if (object == (unsigned)-1)
--    fatal ("unable to mmap file '%s'", name);
--
--  close (fp);
--}
--
--/* Helpers for locatelib.  */
--
--static const char *libname;
--
--static int
--libselect (struct direct *d)
--{
--  return (strncmp (libname, d->d_name, strlen (libname)) == 0);
--}
--
--/* If one file has an additional numeric extension past LIBNAME, then put
--   that one first in the sort.  If both files have additional numeric
--   extensions, then put the one with the higher number first in the sort.
--
--   We must verify that the extension is numeric, because Sun saves the
--   original versions of patched libraries with a .FCS extension.  Files with
--   invalid extensions must go last in the sort, so that they will not be used.  */
--
--static int
--libcompare (struct direct **d1, struct direct **d2)
--{
--  int i1, i2 = strlen (libname);
--  char *e1 = (*d1)->d_name + i2;
--  char *e2 = (*d2)->d_name + i2;
--
--  while (*e1 && *e2 && *e1 == '.' && *e2 == '.'
--	 && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1]))
--    {
--      ++e1;
--      ++e2;
--      i1 = strtol (e1, &e1, 10);
--      i2 = strtol (e2, &e2, 10);
--      if (i1 != i2)
--	return i1 - i2;
--    }
--
--  if (*e1)
--    {
--      /* It has a valid numeric extension, prefer this one.  */
--      if (*e1 == '.' && e1[1] && ISDIGIT (e1[1]))
--	return 1;
--      /* It has an invalid numeric extension, must prefer the other one.  */
--      else
--	return -1;
--    }
--  else if (*e2)
--    {
--      /* It has a valid numeric extension, prefer this one.  */
--      if (*e2 == '.' && e2[1] && ISDIGIT (e2[1]))
--	return -1;
--      /* It has an invalid numeric extension, must prefer the other one.  */
--      else
--	return 1;
--    }
--  else
--    return 0;
--}
--
--/* Given the name NAME of a dynamic dependency, find its pathname and add
--   it to the list of libraries.  */
--
--static void
--locatelib (const char *name)
--{
--  static const char **l;
--  static int cnt;
--  char buf[MAXPATHLEN];
--  char *p, *q;
--  const char **pp;
--
--  if (l == 0)
--    {
--      char *ld_rules;
--      char *ldr = 0;
--      /* counting elements in array, need 1 extra for null */
--      cnt = 1;
--      ld_rules = (char *) (ld_2->ld_rules + code);
--      if (ld_rules)
--	{
--	  cnt++;
--	  for (; *ld_rules != 0; ld_rules++)
--	    if (*ld_rules == ':')
--	      cnt++;
--	  ld_rules = (char *) (ld_2->ld_rules + code);
--	  ldr = xstrdup (ld_rules);
--	}
--      p = getenv ("LD_LIBRARY_PATH");
--      q = 0;
--      if (p)
--	{
--	  cnt++;
--	  for (q = p ; *q != 0; q++)
--	    if (*q == ':')
--	      cnt++;
--	  q = xstrdup (p);
--	}
--      l = xmalloc ((cnt + 3) * sizeof (char *));
--      pp = l;
--      if (ldr)
--	{
--	  *pp++ = ldr;
--	  for (; *ldr != 0; ldr++)
--	    if (*ldr == ':')
--	      {
--		*ldr++ = 0;
--		*pp++ = ldr;
--	      }
--	}
--      if (q)
--	{
--	  *pp++ = q;
--	  for (; *q != 0; q++)
--	    if (*q == ':')
--	      {
--		*q++ = 0;
--		*pp++ = q;
--	      }
--	}
--      /* built in directories are /lib, /usr/lib, and /usr/local/lib */
--      *pp++ = "/lib";
--      *pp++ = "/usr/lib";
--      *pp++ = "/usr/local/lib";
--      *pp = 0;
--    }
--  libname = name;
--  for (pp = l; *pp != 0 ; pp++)
--    {
--      struct direct **namelist;
--      int entries;
--      if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)
--	{
--	  sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);
--	  add_to_list (&libraries, buf);
--	  if (debug)
--	    fprintf (stderr, "%s\n", buf);
--	  break;
--	}
--    }
--  if (*pp == 0)
--    {
--      if (debug)
--	notice ("not found\n");
--      else
--	fatal ("dynamic dependency %s not found", name);
--    }
--}
--
--/* Scan the _DYNAMIC structure of the output file to find shared libraries
--   that it depends upon and any constructors or destructors they contain.  */
--
--static void
--scan_libraries (const char *prog_name)
--{
--  struct exec *header;
--  char *base;
--  struct link_object *lo;
--  char buff[MAXPATHLEN];
--  struct id *list;
--
--  mapfile (prog_name);
--  header = (struct exec *)object;
--  if (N_BADMAG (*header))
--    fatal ("bad magic number in file '%s'", prog_name);
--  if (header->a_dynamic == 0)
--    return;
--
--  code = (char *) (N_TXTOFF (*header) + (long) header);
--  data = (char *) (N_DATOFF (*header) + (long) header);
--  symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
--
--  if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
--    {
--      /* shared object */
--      ld = (struct link_dynamic *) (symtab->n_value + code);
--      base = code;
--    }
--  else
--    {
--      /* executable */
--      ld = (struct link_dynamic *) data;
--      base = code-PAGSIZ;
--    }
--
--  if (debug)
--    notice ("dynamic dependencies.\n");
--
--  ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
--  for (lo = (struct link_object *) ld_2->ld_need; lo;
--       lo = (struct link_object *) lo->lo_next)
--    {
--      char *name;
--      lo = (struct link_object *) ((long) lo + code);
--      name = (char *) (code + lo->lo_name);
--      if (lo->lo_library)
--	{
--	  if (debug)
--	    fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
--	  sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
--	  locatelib (buff);
--	}
--      else
--	{
--	  if (debug)
--	    fprintf (stderr, "\t%s\n", name);
--	  add_to_list (&libraries, name);
--	}
--    }
--
--  if (debug)
--    fprintf (stderr, "\n");
--
--  /* Now iterate through the library list adding their symbols to
--     the list.  */
--  for (list = libraries.first; list; list = list->next)
--    scan_prog_file (list->name, PASS_LIB);
--}
--
--#else  /* SUNOS4_SHARED_LIBRARIES */
--#ifdef LDD_SUFFIX
--
--/* Use the List Dynamic Dependencies program to find shared libraries that
--   the output file depends upon and their initialization/finalization
--   routines, if any.  */
--
--static void
--scan_libraries (const char *prog_name)
--{
--  static struct head libraries;		/* list of shared libraries found */
--  struct id *list;
--  void (*int_handler) (int);
--  void (*quit_handler) (int);
--  char *real_ldd_argv[4];
--  const char **ldd_argv = (const char **) real_ldd_argv;
--  int argc = 0;
--  int pipe_fd[2];
--  char buf[1024];
--  FILE *inf;
--
--  /* If we do not have an `ldd', complain.  */
--  if (ldd_file_name == 0)
--    {
--      error ("cannot find `ldd'");
--      return;
--    }
--
--  ldd_argv[argc++] = ldd_file_name;
--  ldd_argv[argc++] = prog_name;
--  ldd_argv[argc++] = (char *) 0;
--
--  if (pipe (pipe_fd) < 0)
--    fatal_perror ("pipe");
--
--  inf = fdopen (pipe_fd[0], "r");
--  if (inf == (FILE *) 0)
--    fatal_perror ("fdopen");
--
--  /* Trace if needed.  */
--  if (vflag)
--    {
--      const char **p_argv;
--      const char *str;
--
--      for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
--	fprintf (stderr, " %s", str);
--
--      fprintf (stderr, "\n");
--    }
--
--  fflush (stdout);
--  fflush (stderr);
--
--  /* Spawn child ldd on pipe.  */
--  pid = vfork ();
--  if (pid == -1)
--    fatal_perror (VFORK_STRING);
--
--  if (pid == 0)			/* child context */
--    {
--      /* setup stdout */
--      if (dup2 (pipe_fd[1], 1) < 0)
--	fatal_perror ("dup2 %d 1", pipe_fd[1]);
--
--      if (close (pipe_fd[0]) < 0)
--	fatal_perror ("close %d", pipe_fd[0]);
--
--      if (close (pipe_fd[1]) < 0)
--	fatal_perror ("close %d", pipe_fd[1]);
--
--      execv (ldd_file_name, real_ldd_argv);
--      fatal_perror ("execv %s", ldd_file_name);
--    }
--
--  /* Parent context from here on.  */
--  int_handler  = (void (*) (int)) signal (SIGINT,  SIG_IGN);
--#ifdef SIGQUIT
--  quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
--#endif
--
--  if (close (pipe_fd[1]) < 0)
--    fatal_perror ("close %d", pipe_fd[1]);
--
--  if (debug)
--    notice ("\nldd output with constructors/destructors.\n");
--
--  /* Read each line of ldd output.  */
--  while (fgets (buf, sizeof buf, inf) != (char *) 0)
--    {
--      int ch2;
--      char *name, *end, *p = buf;
--
--      /* Extract names of libraries and add to list.  */
--      PARSE_LDD_OUTPUT (p);
--      if (p == 0)
--	continue;
--
--      name = p;
--      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
--	fatal ("dynamic dependency %s not found", buf);
--
--      /* Find the end of the symbol name.  */
--      for (end = p;
--	   (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
--	   end++)
--	continue;
--      *end = '\0';
--
--      if (access (name, R_OK) == 0)
--        add_to_list (&libraries, name);
--      else
--	fatal ("unable to open dynamic dependency '%s'", buf);
--
--      if (debug)
--	fprintf (stderr, "\t%s\n", buf);
--    }
--  if (debug)
--    fprintf (stderr, "\n");
--
--  if (fclose (inf) != 0)
--    fatal_perror ("fclose");
--
--  do_wait (ldd_file_name);
--
--  signal (SIGINT,  int_handler);
--#ifdef SIGQUIT
--  signal (SIGQUIT, quit_handler);
--#endif
--
--  /* Now iterate through the library list adding their symbols to
--     the list.  */
--  for (list = libraries.first; list; list = list->next)
--    scan_prog_file (list->name, PASS_LIB);
--}
--
--#endif /* LDD_SUFFIX */
--#endif /* SUNOS4_SHARED_LIBRARIES */
--
--#endif /* OBJECT_FORMAT_NONE */
--
--
--/*
-- * COFF specific stuff.
-- */
--
--#ifdef OBJECT_FORMAT_COFF
--
--#if defined (EXTENDED_COFF)
--
--#   define GCC_SYMBOLS(X)	(SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
--#   define GCC_SYMENT		SYMR
--#   define GCC_OK_SYMBOL(X)	((X).st == stProc || (X).st == stGlobal)
--#   define GCC_SYMINC(X)	(1)
--#   define GCC_SYMZERO(X)	(SYMHEADER(X).isymMax)
--#   define GCC_CHECK_HDR(X)	(PSYMTAB(X) != 0)
--
--#else
--
--#   define GCC_SYMBOLS(X)	(HEADER(ldptr).f_nsyms)
--#   define GCC_SYMENT		SYMENT
--#   if defined (C_WEAKEXT)
--#     define GCC_OK_SYMBOL(X) \
--       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
--        ((X).n_scnum > N_UNDEF) && \
--        (aix64_flag \
--         || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
--             || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
--#     define GCC_UNDEF_SYMBOL(X) \
--       (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
--        ((X).n_scnum == N_UNDEF))
--#   else
--#     define GCC_OK_SYMBOL(X) \
--       (((X).n_sclass == C_EXT) && \
--        ((X).n_scnum > N_UNDEF) && \
--        (aix64_flag \
--         || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
--             || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
--#     define GCC_UNDEF_SYMBOL(X) \
--       (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
--#   endif
--#   define GCC_SYMINC(X)	((X).n_numaux+1)
--#   define GCC_SYMZERO(X)	0
--
--/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
--#ifdef _AIX51
--#   define GCC_CHECK_HDR(X) \
--     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
--      || (HEADER (X).f_magic == 0767 && aix64_flag))
--#else
--#   define GCC_CHECK_HDR(X) \
--     ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
--      || (HEADER (X).f_magic == 0757 && aix64_flag))
--#endif
--
--#endif
--
--#ifdef COLLECT_EXPORT_LIST
--/* Array of standard AIX libraries which should not
--   be scanned for ctors/dtors.  */
--static const char *const aix_std_libs[] = {
--  "/unix",
--  "/lib/libc.a",
--  "/lib/libm.a",
--  "/lib/libc_r.a",
--  "/lib/libm_r.a",
--  "/usr/lib/libc.a",
--  "/usr/lib/libm.a",
--  "/usr/lib/libc_r.a",
--  "/usr/lib/libm_r.a",
--  "/usr/lib/threads/libc.a",
--  "/usr/ccs/lib/libc.a",
--  "/usr/ccs/lib/libm.a",
--  "/usr/ccs/lib/libc_r.a",
--  "/usr/ccs/lib/libm_r.a",
--  NULL
--};
--
--/* This function checks the filename and returns 1
--   if this name matches the location of a standard AIX library.  */
--static int ignore_library (const char *);
--static int
--ignore_library (const char *name)
--{
--  const char *const *p = &aix_std_libs[0];
--  while (*p++ != NULL)
--    if (! strcmp (name, *p)) return 1;
--  return 0;
--}
--#endif /* COLLECT_EXPORT_LIST */
--
--#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
--extern char *ldgetname (LDFILE *, GCC_SYMENT *);
--#endif
--
--/* COFF version to scan the name list of the loaded program for
--   the symbols g++ uses for static constructors and destructors.
--
--   The constructor table begins at __CTOR_LIST__ and contains a count
--   of the number of pointers (or -1 if the constructors are built in a
--   separate section by the linker), followed by the pointers to the
--   constructor functions, terminated with a null pointer.  The
--   destructor table has the same format, and begins at __DTOR_LIST__.  */
--
--static void
--scan_prog_file (const char *prog_name, enum pass which_pass)
--{
--  LDFILE *ldptr = NULL;
--  int sym_index, sym_count;
--  int is_shared = 0;
--
--  if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
--    return;
--
--#ifdef COLLECT_EXPORT_LIST
--  /* We do not need scanning for some standard C libraries.  */
--  if (which_pass == PASS_FIRST && ignore_library (prog_name))
--    return;
--
--  /* On AIX we have a loop, because there is not much difference
--     between an object and an archive. This trick allows us to
--     eliminate scan_libraries() function.  */
--  do
--    {
--#endif
--      /* Some platforms (e.g. OSF4) declare ldopen as taking a
--         non-const char * filename parameter, even though it will not
--         modify that string.  So we must cast away const-ness here,
--         which will cause -Wcast-qual to burp.  */
--      if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
--	{
--	  if (! MY_ISCOFF (HEADER (ldptr).f_magic))
--	    fatal ("%s: not a COFF file", prog_name);
--
--	  if (GCC_CHECK_HDR (ldptr))
--	    {
--	      sym_count = GCC_SYMBOLS (ldptr);
--	      sym_index = GCC_SYMZERO (ldptr);
--
--#ifdef COLLECT_EXPORT_LIST
--	      /* Is current archive member a shared object?  */
--	      is_shared = HEADER (ldptr).f_flags & F_SHROBJ;
--#endif
--
--	      while (sym_index < sym_count)
--		{
--		  GCC_SYMENT symbol;
--
--		  if (ldtbread (ldptr, sym_index, &symbol) <= 0)
--		    break;
--		  sym_index += GCC_SYMINC (symbol);
--
--		  if (GCC_OK_SYMBOL (symbol))
--		    {
--		      char *name;
--
--		      if ((name = ldgetname (ldptr, &symbol)) == NULL)
--			continue;		/* Should never happen.  */
--
--#ifdef XCOFF_DEBUGGING_INFO
--		      /* All AIX function names have a duplicate entry
--			 beginning with a dot.  */
--		      if (*name == '.')
--			++name;
--#endif
--
--		      switch (is_ctor_dtor (name))
--			{
--			case 1:
--			  if (! is_shared)
--			    add_to_list (&constructors, name);
--#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
--			  if (which_pass == PASS_OBJ)
--			    add_to_list (&exports, name);
--#endif
--			  break;
--
--			case 2:
--			  if (! is_shared)
--			    add_to_list (&destructors, name);
--#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
--			  if (which_pass == PASS_OBJ)
--			    add_to_list (&exports, name);
--#endif
--			  break;
--
--#ifdef COLLECT_EXPORT_LIST
--			case 3:
--#ifndef LD_INIT_SWITCH
--			  if (is_shared)
--			    add_to_list (&constructors, name);
--#endif
--			  break;
--
--			case 4:
--#ifndef LD_INIT_SWITCH
--			  if (is_shared)
--			    add_to_list (&destructors, name);
--#endif
--			  break;
--#endif
--
--			case 5:
--			  if (! is_shared)
--			    add_to_list (&frame_tables, name);
--#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
--			  if (which_pass == PASS_OBJ)
--			    add_to_list (&exports, name);
--#endif
--			  break;
--
--			default:	/* not a constructor or destructor */
--#ifdef COLLECT_EXPORT_LIST
--			  /* Explicitly export all global symbols when
--			     building a shared object on AIX, but do not
--			     re-export symbols from another shared object
--			     and do not export symbols if the user
--			     provides an explicit export list.  */
--			  if (shared_obj && !is_shared
--			      && which_pass == PASS_OBJ && !export_flag)
--			    add_to_list (&exports, name);
--#endif
--			  continue;
--			}
--
--		      if (debug)
--#if !defined(EXTENDED_COFF)
--			fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n",
--				 symbol.n_scnum, symbol.n_sclass,
--				 (symbol.n_type ? "0" : ""), symbol.n_type,
--				 name);
--#else
--			fprintf (stderr,
--				 "\tiss = %5d, value = %5ld, index = %5d, name = %s\n",
--				 symbol.iss, (long) symbol.value, symbol.index, name);
--#endif
--		    }
--		}
--	    }
--#ifdef COLLECT_EXPORT_LIST
--	  else
--	    {
--	      /* If archive contains both 32-bit and 64-bit objects,
--		 we want to skip objects in other mode so mismatch normal.  */
--	      if (debug)
--		fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n",
--			 prog_name, HEADER (ldptr).f_magic, aix64_flag);
--	    }
--#endif
--	}
--      else
--	{
--	  fatal ("%s: cannot open as COFF file", prog_name);
--	}
--#ifdef COLLECT_EXPORT_LIST
--      /* On AIX loop continues while there are more members in archive.  */
--    }
--  while (ldclose (ldptr) == FAILURE);
--#else
--  /* Otherwise we simply close ldptr.  */
--  (void) ldclose(ldptr);
--#endif
--}
--#endif /* OBJECT_FORMAT_COFF */
--
--#ifdef COLLECT_EXPORT_LIST
--/* Given a library name without "lib" prefix, this function
--   returns a full library name including a path.  */
--static char *
--resolve_lib_name (const char *name)
--{
--  char *lib_buf;
--  int i, j, l = 0;
--  /* Library extensions for AIX dynamic linking.  */
--  const char * const libexts[2] = {"a", "so"};
--
--  for (i = 0; libpaths[i]; i++)
--    if (libpaths[i]->max_len > l)
--      l = libpaths[i]->max_len;
--
--  lib_buf = xmalloc (l + strlen(name) + 10);
--
--  for (i = 0; libpaths[i]; i++)
--    {
--      struct prefix_list *list = libpaths[i]->plist;
--      for (; list; list = list->next)
--	{
--	  /* The following lines are needed because path_prefix list
--	     may contain directories both with trailing '/' and
--	     without it.  */
--	  const char *p = "";
--	  if (list->prefix[strlen(list->prefix)-1] != '/')
--	    p = "/";
--	  for (j = 0; j < 2; j++)
--	    {
--	      sprintf (lib_buf, "%s%slib%s.%s",
--		       list->prefix, p, name,
--		       libexts[(j + aixrtl_flag) % 2]);
--	      if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
--	      if (file_exists (lib_buf))
--		{
--		  if (debug) fprintf (stderr, "found: %s\n", lib_buf);
--		  return (lib_buf);
--		}
--	    }
--	}
--    }
--  if (debug)
--    fprintf (stderr, "not found\n");
--  else
--    fatal ("library lib%s not found", name);
--  return (NULL);
--}
--#endif /* COLLECT_EXPORT_LIST */
-diff -ruN gcc-3.4.5-20060117-1/gcc/config/i386/cygming.h.orig gcc-3.4.5-20060117-1-winelf/gcc/config/i386/cygming.h.orig
---- gcc-3.4.5-20060117-1/gcc/config/i386/cygming.h.orig	2004-06-07 23:30:32.000000000 -0700
-+++ gcc-3.4.5-20060117-1-winelf/gcc/config/i386/cygming.h.orig	1969-12-31 16:00:00.000000000 -0800
-@@ -1,391 +0,0 @@
--/* Operating system specific defines to be used when targeting GCC for
--   hosting on Windows32, using a Unix style C library and tools.
--   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
--   Free Software Foundation, Inc.
--
--This file is part of GCC.
--
--GCC is free software; you can redistribute it and/or modify
--it under the terms of the GNU General Public License as published by
--the Free Software Foundation; either version 2, or (at your option)
--any later version.
--
--GCC is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--GNU General Public License for more details.
--
--You should have received a copy of the GNU General Public License
--along with GCC; see the file COPYING.  If not, write to
--the Free Software Foundation, 59 Temple Place - Suite 330,
--Boston, MA 02111-1307, USA.  */
--
--#define DBX_DEBUGGING_INFO 1
--#define SDB_DEBUGGING_INFO 1
--#undef PREFERRED_DEBUGGING_TYPE
--#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
--
--#define TARGET_EXECUTABLE_SUFFIX ".exe"
--
--#define TARGET_IS_PE_COFF 1
--
--#include <stdio.h>
--
--/* Masks for subtarget switches used by other files.  */
--#define MASK_NOP_FUN_DLLIMPORT 0x08000000 /* Ignore dllimport for functions */
--
--/* Used in winnt.c.  */
--#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT)
--
--#undef  SUBTARGET_SWITCHES
--#define SUBTARGET_SWITCHES \
--{ "cygwin",		  0, N_("Use the Cygwin interface") },	\
--{ "no-cygwin",		  0, N_("Use the Mingw32 interface") },	\
--{ "windows",		  0, N_("Create GUI application") },	\
--{ "no-win32",		  0, N_("Don't set Windows defines") },	\
--{ "win32",		  0, N_("Set Windows defines") },	\
--{ "console",		  0, N_("Create console application") },\
--{ "dll",		  0, N_("Generate code for a DLL") },	\
--{ "nop-fun-dllimport",	  MASK_NOP_FUN_DLLIMPORT,		\
--  N_("Ignore dllimport for functions") },			\
--{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" },	\
--{ "threads",		  0, N_("Use Mingw-specific thread support") },
--
--#define MAYBE_UWIN_CPP_BUILTINS() /* Nothing.  */
--
--/* Support the __declspec keyword by turning them into attributes.
--   We currently only support: dllimport and dllexport.
--   Note that the current way we do this may result in a collision with
--   predefined attributes later on.  This can be solved by using one attribute,
--   say __declspec__, and passing args to it.  The problem with that approach
--   is that args are not accumulated: each new appearance would clobber any
--   existing args.  */
--
--#define TARGET_OS_CPP_BUILTINS()					\
--  do									\
--    {									\
--	builtin_define ("_X86_=1");					\
--	builtin_assert ("system=winnt");				\
--	builtin_define ("__stdcall=__attribute__((__stdcall__))");	\
--	builtin_define ("__fastcall=__attribute__((__fastcall__))");	\
--	builtin_define ("__cdecl=__attribute__((__cdecl__))");		\
--	builtin_define ("__declspec(x)=__attribute__((x))");		\
--	if (!flag_iso)							\
--	  {								\
--	    builtin_define ("_stdcall=__attribute__((__stdcall__))");	\
--	    builtin_define ("_fastcall=__attribute__((__fastcall__))");	\
--	    builtin_define ("_cdecl=__attribute__((__cdecl__))");	\
--	  }								\
--	MAYBE_UWIN_CPP_BUILTINS ();					\
--	EXTRA_OS_CPP_BUILTINS ();					\
--  }									\
--  while (0)
--
--/* Get tree.c to declare a target-specific specialization of
--   merge_decl_attributes.  */
--#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
--
--/* This macro defines names of additional specifications to put in the specs
--   that can be used in various specifications like CC1_SPEC.  Its definition
--   is an initializer with a subgrouping for each command option.
--
--   Each subgrouping contains a string constant, that defines the
--   specification name, and a string constant that used by the GCC driver
--   program.
--
--   Do not define this macro if it does not need to do anything.  */
--
--#undef  SUBTARGET_EXTRA_SPECS
--#define SUBTARGET_EXTRA_SPECS						\
--  { "mingw_include_path", DEFAULT_TARGET_MACHINE }
--
--#undef MATH_LIBRARY
--#define MATH_LIBRARY ""
--
--#define SIZE_TYPE "unsigned int"
--#define PTRDIFF_TYPE "int"
--#define WCHAR_TYPE_SIZE 16
--#define WCHAR_TYPE "short unsigned int"
--
--
--/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop).  */
--#define HANDLE_PRAGMA_PACK_PUSH_POP 1
--
--union tree_node;
--#define TREE union tree_node *
--
--#undef EXTRA_SECTIONS
--#define EXTRA_SECTIONS in_drectve
--
--#undef EXTRA_SECTION_FUNCTIONS
--#define EXTRA_SECTION_FUNCTIONS					\
--  DRECTVE_SECTION_FUNCTION					\
--  SWITCH_TO_SECTION_FUNCTION
--
--#define DRECTVE_SECTION_FUNCTION \
--void									\
--drectve_section (void)							\
--{									\
--  if (in_section != in_drectve)						\
--    {									\
--      fprintf (asm_out_file, "%s\n", "\t.section .drectve\n");		\
--      in_section = in_drectve;						\
--    }									\
--}
--void drectve_section (void);
--
--/* Older versions of gas don't handle 'r' as data.
--   Explicitly set data flag with 'd'.  */  
--#define READONLY_DATA_SECTION_ASM_OP "\t.section .rdata,\"dr\""
--
--/* Switch to SECTION (an `enum in_section').
--
--   ??? This facility should be provided by GCC proper.
--   The problem is that we want to temporarily switch sections in
--   ASM_DECLARE_OBJECT_NAME and then switch back to the original section
--   afterwards.  */
--#define SWITCH_TO_SECTION_FUNCTION				\
--void switch_to_section (enum in_section, tree);			\
--void								\
--switch_to_section (enum in_section section, tree decl)		\
--{								\
--  switch (section)						\
--    {								\
--      case in_text: text_section (); break;			\
--      case in_data: data_section (); break;			\
--      case in_readonly_data: readonly_data_section (); break;	\
--      case in_named: named_section (decl, NULL, 0); break;	\
--      case in_drectve: drectve_section (); break;		\
--      default: abort (); break;				\
--    }								\
--}
--
--/* Don't allow flag_pic to propagate since gas may produce invalid code
--   otherwise.  */
--
--#undef  SUBTARGET_OVERRIDE_OPTIONS
--#define SUBTARGET_OVERRIDE_OPTIONS					\
--do {									\
--  if (flag_pic)								\
--    {									\
--      warning ("-f%s ignored for target (all code is position independent)",\
--	       (flag_pic > 1) ? "PIC" : "pic");				\
--      flag_pic = 0;							\
--    }									\
--} while (0)								\
--
--/* Define this macro if references to a symbol must be treated
--   differently depending on something about the variable or
--   function named by the symbol (such as what section it is in).
--
--   On i386 running Windows NT, modify the assembler name with a suffix
--   consisting of an atsign (@) followed by string of digits that represents
--   the number of bytes of arguments passed to the function, if it has the
--   attribute STDCALL.
--
--   In addition, we must mark dll symbols specially. Definitions of
--   dllexport'd objects install some info in the .drectve section.
--   References to dllimport'd objects are fetched indirectly via
--   _imp__.  If both are declared, dllexport overrides.  This is also
--   needed to implement one-only vtables: they go into their own
--   section and we need to set DECL_SECTION_NAME so we do that here.
--   Note that we can be called twice on the same decl.  */
--
--#undef TARGET_ENCODE_SECTION_INFO
--#define TARGET_ENCODE_SECTION_INFO  i386_pe_encode_section_info
--#undef  TARGET_STRIP_NAME_ENCODING
--#define TARGET_STRIP_NAME_ENCODING  i386_pe_strip_name_encoding_full
--
--/* Output a reference to a label.  */
--#undef ASM_OUTPUT_LABELREF
--#define ASM_OUTPUT_LABELREF  i386_pe_output_labelref
--
--/* Output a common block.  */
--#undef ASM_OUTPUT_COMMON
--#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED)	\
--do {							\
--  if (i386_pe_dllexport_name_p (NAME))			\
--    i386_pe_record_exported_symbol (NAME, 1);		\
--  if (! i386_pe_dllimport_name_p (NAME))		\
--    {							\
--      fprintf ((STREAM), "\t.comm\t");			\
--      assemble_name ((STREAM), (NAME));			\
--      fprintf ((STREAM), ", %d\t%s %d\n",		\
--	       (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE));	\
--    }							\
--} while (0)
--
--/* Output the label for an initialized variable.  */
--#undef ASM_DECLARE_OBJECT_NAME
--#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL)	\
--do {							\
--  if (i386_pe_dllexport_name_p (NAME))			\
--    i386_pe_record_exported_symbol (NAME, 1);		\
--  ASM_OUTPUT_LABEL ((STREAM), (NAME));			\
--} while (0)
--
--
--/* Emit code to check the stack when allocating more that 4000
--   bytes in one go.  */
--
--#define CHECK_STACK_LIMIT 4000
--
--/* By default, target has a 80387, uses IEEE compatible arithmetic,
--   returns float values in the 387 and needs stack probes.
--   We also align doubles to 64-bits for MSVC default compatibility.  */
--
--#undef TARGET_SUBTARGET_DEFAULT
--#define TARGET_SUBTARGET_DEFAULT \
--   (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE \
--    | MASK_ALIGN_DOUBLE)
--
--/* This is how to output an assembler line
--   that says to advance the location counter
--   to a multiple of 2**LOG bytes.  */
--
--#undef ASM_OUTPUT_ALIGN
--#define ASM_OUTPUT_ALIGN(FILE,LOG)	\
--    if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
--
--/* Define this macro if in some cases global symbols from one translation
--   unit may not be bound to undefined symbols in another translation unit
--   without user intervention.  For instance, under Microsoft Windows
--   symbols must be explicitly imported from shared libraries (DLLs).  */
--#define MULTIPLE_SYMBOL_SPACES
--
--extern void i386_pe_unique_section (TREE, int);
--#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
--
--#define SUPPORTS_ONE_ONLY 1
--
--/* Switch into a generic section.  */
--#define TARGET_ASM_NAMED_SECTION  i386_pe_asm_named_section
--
--/* Select attributes for named sections.  */
--#define TARGET_SECTION_TYPE_FLAGS  i386_pe_section_type_flags
--
--/* Write the extra assembler code needed to declare a function
--   properly.  If we are generating SDB debugging information, this
--   will happen automatically, so we only need to handle other cases.  */
--#undef ASM_DECLARE_FUNCTION_NAME
--#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
--  do									\
--    {									\
--      if (i386_pe_dllexport_name_p (NAME))				\
--	i386_pe_record_exported_symbol (NAME, 0);			\
--      if (write_symbols != SDB_DEBUG)					\
--	i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL));	\
--      ASM_OUTPUT_LABEL (FILE, NAME);					\
--    }									\
--  while (0)
--
--/* Add an external function to the list of functions to be declared at
--   the end of the file.  */
--#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)				\
--  do									\
--    {									\
--      if (TREE_CODE (DECL) == FUNCTION_DECL)				\
--	i386_pe_record_external_function (NAME);			\
--    }									\
--  while (0)
--
--/* Declare the type properly for any external libcall.  */
--#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
--  i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
--
--/* This says out to put a global symbol in the BSS section.  */
--#undef ASM_OUTPUT_ALIGNED_BSS
--#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
--  asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
--
--/* Output function declarations at the end of the file.  */
--#undef TARGET_ASM_FILE_END
--#define TARGET_ASM_FILE_END i386_pe_file_end
--
--#undef ASM_COMMENT_START
--#define ASM_COMMENT_START " #"
--
--/* DWARF2 Unwinding doesn't work with exception handling yet.  To make
--   it work, we need to build a libgcc_s.dll, and dcrt0.o should be
--   changed to call __register_frame_info/__deregister_frame_info.  */
--#define DWARF2_UNWIND_INFO 0
--
--/* Don't assume anything about the header files.  */
--#define NO_IMPLICIT_EXTERN_C
--
--#undef PROFILE_HOOK
--#define PROFILE_HOOK(LABEL)						\
--  if (MAIN_NAME_P (DECL_NAME (current_function_decl)))			\
--    {									\
--      emit_call_insn (gen_rtx (CALL, VOIDmode,				\
--	gen_rtx_MEM (FUNCTION_MODE,					\
--		     gen_rtx_SYMBOL_REF (Pmode, "_monstartup")),	\
--	const0_rtx));							\
--    }
--
--/* Java Native Interface (JNI) methods on Win32 are invoked using the
--   stdcall calling convention.  */
--#undef MODIFY_JNI_METHOD_CALL
--#define MODIFY_JNI_METHOD_CALL(MDECL)					      \
--  build_type_attribute_variant ((MDECL),				      \
--			       build_tree_list (get_identifier ("stdcall"),   \
--						NULL))
--
--/* External function declarations.  */
--
--extern void i386_pe_record_external_function (const char *);
--extern void i386_pe_declare_function_type (FILE *, const char *, int);
--extern void i386_pe_record_exported_symbol (const char *, int);
--extern void i386_pe_file_end (void);
--extern int i386_pe_dllexport_name_p (const char *);
--extern int i386_pe_dllimport_name_p (const char *);
--
--/* For Win32 ABI compatibility */
--#undef DEFAULT_PCC_STRUCT_RETURN
--#define DEFAULT_PCC_STRUCT_RETURN 0
--
--/* MSVC returns aggregate types of up to 8 bytes via registers.
--   See i386.c:ix86_return_in_memory.  */
--#undef MS_AGGREGATE_RETURN
--#define MS_AGGREGATE_RETURN 1
--
--/* No data type wants to be aligned rounder than this.  */
--#undef	BIGGEST_ALIGNMENT
--#define BIGGEST_ALIGNMENT 128
--
--/* Native complier aligns internal doubles in structures on dword boundaries.  */
--#undef	BIGGEST_FIELD_ALIGNMENT
--#define BIGGEST_FIELD_ALIGNMENT 64
--
--/* A bit-field declared as `int' forces `int' alignment for the struct.  */
--#undef PCC_BITFIELD_TYPE_MATTERS
--#define PCC_BITFIELD_TYPE_MATTERS 1
--#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
--
--/* Enable alias attribute support.  */
--#ifndef SET_ASM_OP
--#define SET_ASM_OP "\t.set\t"
--#endif
--/* This implements the `alias' attribute, keeping any stdcall or
--   fastcall decoration.  */
--#undef	ASM_OUTPUT_DEF_FROM_DECLS
--#define	ASM_OUTPUT_DEF_FROM_DECLS(STREAM, DECL, TARGET) 		\
--  do									\
--    {									\
--      const char *alias;						\
--      rtx rtlname = XEXP (DECL_RTL (DECL), 0);				\
--      if (GET_CODE (rtlname) == SYMBOL_REF)				\
--	alias = XSTR (rtlname, 0);					\
--      else								\
--	abort ();							\
--      if (TREE_CODE (DECL) == FUNCTION_DECL)				\
--	i386_pe_declare_function_type (STREAM, alias,			\
--				       TREE_PUBLIC (DECL));		\
--      ASM_OUTPUT_DEF (STREAM, alias, IDENTIFIER_POINTER (TARGET));	\
--    } while (0)
--
--#undef TREE
--
--#ifndef BUFSIZ
--# undef FILE
--#endif
-diff -ruN gcc-3.4.5-20060117-1/gcc/config/i386/i386.c.orig gcc-3.4.5-20060117-1-winelf/gcc/config/i386/i386.c.orig
---- gcc-3.4.5-20060117-1/gcc/config/i386/i386.c.orig	2005-08-03 07:15:28.000000000 -0700
-+++ gcc-3.4.5-20060117-1-winelf/gcc/config/i386/i386.c.orig	1969-12-31 16:00:00.000000000 -0800
-@@ -1,16094 +0,0 @@
--/* Subroutines used for code generation on IA-32.
--   Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
--   2002, 2003, 2004 Free Software Foundation, Inc.
--
--This file is part of GCC.
--
--GCC is free software; you can redistribute it and/or modify
--it under the terms of the GNU General Public License as published by
--the Free Software Foundation; either version 2, or (at your option)
--any later version.
--
--GCC is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--GNU General Public License for more details.
--
--You should have received a copy of the GNU General Public License
--along with GCC; see the file COPYING.  If not, write to
--the Free Software Foundation, 59 Temple Place - Suite 330,
--Boston, MA 02111-1307, USA.  */
--
--#include "config.h"
--#include "system.h"
--#include "coretypes.h"
--#include "tm.h"
--#include "rtl.h"
--#include "tree.h"
--#include "tm_p.h"
--#include "regs.h"
--#include "hard-reg-set.h"
--#include "real.h"
--#include "insn-config.h"
--#include "conditions.h"
--#include "output.h"
--#include "insn-attr.h"
--#include "flags.h"
--#include "except.h"
--#include "function.h"
--#include "recog.h"
--#include "expr.h"
--#include "optabs.h"
--#include "toplev.h"
--#include "basic-block.h"
--#include "ggc.h"
--#include "target.h"
--#include "target-def.h"
--#include "langhooks.h"
--#include "cgraph.h"
--
--#ifndef CHECK_STACK_LIMIT
--#define CHECK_STACK_LIMIT (-1)
--#endif
--
--/* Return index of given mode in mult and division cost tables.  */
--#define MODE_INDEX(mode)					\
--  ((mode) == QImode ? 0						\
--   : (mode) == HImode ? 1					\
--   : (mode) == SImode ? 2					\
--   : (mode) == DImode ? 3					\
--   : 4)
--
--/* Processor costs (relative to an add) */
--static const
--struct processor_costs size_cost = {	/* costs for tunning for size */
--  2,					/* cost of an add instruction */
--  3,					/* cost of a lea instruction */
--  2,					/* variable shift costs */
--  3,					/* constant shift costs */
--  {3, 3, 3, 3, 5},			/* cost of starting a multiply */
--  0,					/* cost of multiply per each bit set */
--  {3, 3, 3, 3, 5},			/* cost of a divide/mod */
--  3,					/* cost of movsx */
--  3,					/* cost of movzx */
--  0,					/* "large" insn */
--  2,					/* MOVE_RATIO */
--  2,					/* cost for loading QImode using movzbl */
--  {2, 2, 2},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {2, 2, 2},				/* cost of storing integer registers */
--  2,					/* cost of reg,reg fld/fst */
--  {2, 2, 2},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {2, 2, 2},				/* cost of loading integer registers */
--  3,					/* cost of moving MMX register */
--  {3, 3},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {3, 3},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  3,					/* cost of moving SSE register */
--  {3, 3, 3},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {3, 3, 3},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  3,					/* MMX or SSE register to integer */
--  0,					/* size of prefetch block */
--  0,					/* number of parallel prefetches */
--  1,					/* Branch cost */
--  2,					/* cost of FADD and FSUB insns.  */
--  2,					/* cost of FMUL instruction.  */
--  2,					/* cost of FDIV instruction.  */
--  2,					/* cost of FABS instruction.  */
--  2,					/* cost of FCHS instruction.  */
--  2,					/* cost of FSQRT instruction.  */
--};
--
--/* Processor costs (relative to an add) */
--static const
--struct processor_costs i386_cost = {	/* 386 specific costs */
--  1,					/* cost of an add instruction */
--  1,					/* cost of a lea instruction */
--  3,					/* variable shift costs */
--  2,					/* constant shift costs */
--  {6, 6, 6, 6, 6},			/* cost of starting a multiply */
--  1,					/* cost of multiply per each bit set */
--  {23, 23, 23, 23, 23},			/* cost of a divide/mod */
--  3,					/* cost of movsx */
--  2,					/* cost of movzx */
--  15,					/* "large" insn */
--  3,					/* MOVE_RATIO */
--  4,					/* cost for loading QImode using movzbl */
--  {2, 4, 2},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {2, 4, 2},				/* cost of storing integer registers */
--  2,					/* cost of reg,reg fld/fst */
--  {8, 8, 8},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {8, 8, 8},				/* cost of loading integer registers */
--  2,					/* cost of moving MMX register */
--  {4, 8},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {4, 8},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  2,					/* cost of moving SSE register */
--  {4, 8, 16},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {4, 8, 16},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  3,					/* MMX or SSE register to integer */
--  0,					/* size of prefetch block */
--  0,					/* number of parallel prefetches */
--  1,					/* Branch cost */
--  23,					/* cost of FADD and FSUB insns.  */
--  27,					/* cost of FMUL instruction.  */
--  88,					/* cost of FDIV instruction.  */
--  22,					/* cost of FABS instruction.  */
--  24,					/* cost of FCHS instruction.  */
--  122,					/* cost of FSQRT instruction.  */
--};
--
--static const
--struct processor_costs i486_cost = {	/* 486 specific costs */
--  1,					/* cost of an add instruction */
--  1,					/* cost of a lea instruction */
--  3,					/* variable shift costs */
--  2,					/* constant shift costs */
--  {12, 12, 12, 12, 12},			/* cost of starting a multiply */
--  1,					/* cost of multiply per each bit set */
--  {40, 40, 40, 40, 40},			/* cost of a divide/mod */
--  3,					/* cost of movsx */
--  2,					/* cost of movzx */
--  15,					/* "large" insn */
--  3,					/* MOVE_RATIO */
--  4,					/* cost for loading QImode using movzbl */
--  {2, 4, 2},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {2, 4, 2},				/* cost of storing integer registers */
--  2,					/* cost of reg,reg fld/fst */
--  {8, 8, 8},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {8, 8, 8},				/* cost of loading integer registers */
--  2,					/* cost of moving MMX register */
--  {4, 8},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {4, 8},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  2,					/* cost of moving SSE register */
--  {4, 8, 16},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {4, 8, 16},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  3,					/* MMX or SSE register to integer */
--  0,					/* size of prefetch block */
--  0,					/* number of parallel prefetches */
--  1,					/* Branch cost */
--  8,					/* cost of FADD and FSUB insns.  */
--  16,					/* cost of FMUL instruction.  */
--  73,					/* cost of FDIV instruction.  */
--  3,					/* cost of FABS instruction.  */
--  3,					/* cost of FCHS instruction.  */
--  83,					/* cost of FSQRT instruction.  */
--};
--
--static const
--struct processor_costs pentium_cost = {
--  1,					/* cost of an add instruction */
--  1,					/* cost of a lea instruction */
--  4,					/* variable shift costs */
--  1,					/* constant shift costs */
--  {11, 11, 11, 11, 11},			/* cost of starting a multiply */
--  0,					/* cost of multiply per each bit set */
--  {25, 25, 25, 25, 25},			/* cost of a divide/mod */
--  3,					/* cost of movsx */
--  2,					/* cost of movzx */
--  8,					/* "large" insn */
--  6,					/* MOVE_RATIO */
--  6,					/* cost for loading QImode using movzbl */
--  {2, 4, 2},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {2, 4, 2},				/* cost of storing integer registers */
--  2,					/* cost of reg,reg fld/fst */
--  {2, 2, 6},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {4, 4, 6},				/* cost of loading integer registers */
--  8,					/* cost of moving MMX register */
--  {8, 8},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {8, 8},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  2,					/* cost of moving SSE register */
--  {4, 8, 16},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {4, 8, 16},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  3,					/* MMX or SSE register to integer */
--  0,					/* size of prefetch block */
--  0,					/* number of parallel prefetches */
--  2,					/* Branch cost */
--  3,					/* cost of FADD and FSUB insns.  */
--  3,					/* cost of FMUL instruction.  */
--  39,					/* cost of FDIV instruction.  */
--  1,					/* cost of FABS instruction.  */
--  1,					/* cost of FCHS instruction.  */
--  70,					/* cost of FSQRT instruction.  */
--};
--
--static const
--struct processor_costs pentiumpro_cost = {
--  1,					/* cost of an add instruction */
--  1,					/* cost of a lea instruction */
--  1,					/* variable shift costs */
--  1,					/* constant shift costs */
--  {4, 4, 4, 4, 4},			/* cost of starting a multiply */
--  0,					/* cost of multiply per each bit set */
--  {17, 17, 17, 17, 17},			/* cost of a divide/mod */
--  1,					/* cost of movsx */
--  1,					/* cost of movzx */
--  8,					/* "large" insn */
--  6,					/* MOVE_RATIO */
--  2,					/* cost for loading QImode using movzbl */
--  {4, 4, 4},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {2, 2, 2},				/* cost of storing integer registers */
--  2,					/* cost of reg,reg fld/fst */
--  {2, 2, 6},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {4, 4, 6},				/* cost of loading integer registers */
--  2,					/* cost of moving MMX register */
--  {2, 2},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {2, 2},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  2,					/* cost of moving SSE register */
--  {2, 2, 8},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {2, 2, 8},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  3,					/* MMX or SSE register to integer */
--  32,					/* size of prefetch block */
--  6,					/* number of parallel prefetches */
--  2,					/* Branch cost */
--  3,					/* cost of FADD and FSUB insns.  */
--  5,					/* cost of FMUL instruction.  */
--  56,					/* cost of FDIV instruction.  */
--  2,					/* cost of FABS instruction.  */
--  2,					/* cost of FCHS instruction.  */
--  56,					/* cost of FSQRT instruction.  */
--};
--
--static const
--struct processor_costs k6_cost = {
--  1,					/* cost of an add instruction */
--  2,					/* cost of a lea instruction */
--  1,					/* variable shift costs */
--  1,					/* constant shift costs */
--  {3, 3, 3, 3, 3},			/* cost of starting a multiply */
--  0,					/* cost of multiply per each bit set */
--  {18, 18, 18, 18, 18},			/* cost of a divide/mod */
--  2,					/* cost of movsx */
--  2,					/* cost of movzx */
--  8,					/* "large" insn */
--  4,					/* MOVE_RATIO */
--  3,					/* cost for loading QImode using movzbl */
--  {4, 5, 4},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {2, 3, 2},				/* cost of storing integer registers */
--  4,					/* cost of reg,reg fld/fst */
--  {6, 6, 6},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {4, 4, 4},				/* cost of loading integer registers */
--  2,					/* cost of moving MMX register */
--  {2, 2},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {2, 2},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  2,					/* cost of moving SSE register */
--  {2, 2, 8},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {2, 2, 8},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  6,					/* MMX or SSE register to integer */
--  32,					/* size of prefetch block */
--  1,					/* number of parallel prefetches */
--  1,					/* Branch cost */
--  2,					/* cost of FADD and FSUB insns.  */
--  2,					/* cost of FMUL instruction.  */
--  56,					/* cost of FDIV instruction.  */
--  2,					/* cost of FABS instruction.  */
--  2,					/* cost of FCHS instruction.  */
--  56,					/* cost of FSQRT instruction.  */
--};
--
--static const
--struct processor_costs athlon_cost = {
--  1,					/* cost of an add instruction */
--  2,					/* cost of a lea instruction */
--  1,					/* variable shift costs */
--  1,					/* constant shift costs */
--  {5, 5, 5, 5, 5},			/* cost of starting a multiply */
--  0,					/* cost of multiply per each bit set */
--  {18, 26, 42, 74, 74},			/* cost of a divide/mod */
--  1,					/* cost of movsx */
--  1,					/* cost of movzx */
--  8,					/* "large" insn */
--  9,					/* MOVE_RATIO */
--  4,					/* cost for loading QImode using movzbl */
--  {3, 4, 3},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {3, 4, 3},				/* cost of storing integer registers */
--  4,					/* cost of reg,reg fld/fst */
--  {4, 4, 12},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {6, 6, 8},				/* cost of loading integer registers */
--  2,					/* cost of moving MMX register */
--  {4, 4},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {4, 4},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  2,					/* cost of moving SSE register */
--  {4, 4, 6},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {4, 4, 5},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  5,					/* MMX or SSE register to integer */
--  64,					/* size of prefetch block */
--  6,					/* number of parallel prefetches */
--  2,					/* Branch cost */
--  4,					/* cost of FADD and FSUB insns.  */
--  4,					/* cost of FMUL instruction.  */
--  24,					/* cost of FDIV instruction.  */
--  2,					/* cost of FABS instruction.  */
--  2,					/* cost of FCHS instruction.  */
--  35,					/* cost of FSQRT instruction.  */
--};
--
--static const
--struct processor_costs k8_cost = {
--  1,					/* cost of an add instruction */
--  2,					/* cost of a lea instruction */
--  1,					/* variable shift costs */
--  1,					/* constant shift costs */
--  {3, 4, 3, 4, 5},			/* cost of starting a multiply */
--  0,					/* cost of multiply per each bit set */
--  {18, 26, 42, 74, 74},			/* cost of a divide/mod */
--  1,					/* cost of movsx */
--  1,					/* cost of movzx */
--  8,					/* "large" insn */
--  9,					/* MOVE_RATIO */
--  4,					/* cost for loading QImode using movzbl */
--  {3, 4, 3},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {3, 4, 3},				/* cost of storing integer registers */
--  4,					/* cost of reg,reg fld/fst */
--  {4, 4, 12},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {6, 6, 8},				/* cost of loading integer registers */
--  2,					/* cost of moving MMX register */
--  {3, 3},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {4, 4},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  2,					/* cost of moving SSE register */
--  {4, 3, 6},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {4, 4, 5},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  5,					/* MMX or SSE register to integer */
--  64,					/* size of prefetch block */
--  6,					/* number of parallel prefetches */
--  2,					/* Branch cost */
--  4,					/* cost of FADD and FSUB insns.  */
--  4,					/* cost of FMUL instruction.  */
--  19,					/* cost of FDIV instruction.  */
--  2,					/* cost of FABS instruction.  */
--  2,					/* cost of FCHS instruction.  */
--  35,					/* cost of FSQRT instruction.  */
--};
--
--static const
--struct processor_costs pentium4_cost = {
--  1,					/* cost of an add instruction */
--  1,					/* cost of a lea instruction */
--  4,					/* variable shift costs */
--  4,					/* constant shift costs */
--  {15, 15, 15, 15, 15},			/* cost of starting a multiply */
--  0,					/* cost of multiply per each bit set */
--  {56, 56, 56, 56, 56},			/* cost of a divide/mod */
--  1,					/* cost of movsx */
--  1,					/* cost of movzx */
--  16,					/* "large" insn */
--  6,					/* MOVE_RATIO */
--  2,					/* cost for loading QImode using movzbl */
--  {4, 5, 4},				/* cost of loading integer registers
--					   in QImode, HImode and SImode.
--					   Relative to reg-reg move (2).  */
--  {2, 3, 2},				/* cost of storing integer registers */
--  2,					/* cost of reg,reg fld/fst */
--  {2, 2, 6},				/* cost of loading fp registers
--					   in SFmode, DFmode and XFmode */
--  {4, 4, 6},				/* cost of loading integer registers */
--  2,					/* cost of moving MMX register */
--  {2, 2},				/* cost of loading MMX registers
--					   in SImode and DImode */
--  {2, 2},				/* cost of storing MMX registers
--					   in SImode and DImode */
--  12,					/* cost of moving SSE register */
--  {12, 12, 12},				/* cost of loading SSE registers
--					   in SImode, DImode and TImode */
--  {2, 2, 8},				/* cost of storing SSE registers
--					   in SImode, DImode and TImode */
--  10,					/* MMX or SSE register to integer */
--  64,					/* size of prefetch block */
--  6,					/* number of parallel prefetches */
--  2,					/* Branch cost */
--  5,					/* cost of FADD and FSUB insns.  */
--  7,					/* cost of FMUL instruction.  */
--  43,					/* cost of FDIV instruction.  */
--  2,					/* cost of FABS instruction.  */
--  2,					/* cost of FCHS instruction.  */
--  43,					/* cost of FSQRT instruction.  */
--};
--
--const struct processor_costs *ix86_cost = &pentium_cost;
--
--/* Processor feature/optimization bitmasks.  */
--#define m_386 (1<<PROCESSOR_I386)
--#define m_486 (1<<PROCESSOR_I486)
--#define m_PENT (1<<PROCESSOR_PENTIUM)
--#define m_PPRO (1<<PROCESSOR_PENTIUMPRO)
--#define m_K6  (1<<PROCESSOR_K6)
--#define m_ATHLON  (1<<PROCESSOR_ATHLON)
--#define m_PENT4  (1<<PROCESSOR_PENTIUM4)
--#define m_K8  (1<<PROCESSOR_K8)
--#define m_ATHLON_K8  (m_K8 | m_ATHLON)
--
--const int x86_use_leave = m_386 | m_K6 | m_ATHLON_K8;
--const int x86_push_memory = m_386 | m_K6 | m_ATHLON_K8 | m_PENT4;
--const int x86_zero_extend_with_and = m_486 | m_PENT;
--const int x86_movx = m_ATHLON_K8 | m_PPRO | m_PENT4 /* m_386 | m_K6 */;
--const int x86_double_with_add = ~m_386;
--const int x86_use_bit_test = m_386;
--const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON_K8 | m_K6;
--const int x86_cmove = m_PPRO | m_ATHLON_K8 | m_PENT4;
--const int x86_3dnow_a = m_ATHLON_K8;
--const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON_K8 | m_PENT4;
--const int x86_branch_hints = m_PENT4;
--const int x86_use_sahf = m_PPRO | m_K6 | m_PENT4;
--const int x86_partial_reg_stall = m_PPRO;
--const int x86_use_loop = m_K6;
--const int x86_use_fiop = ~(m_PPRO | m_ATHLON_K8 | m_PENT);
--const int x86_use_mov0 = m_K6;
--const int x86_use_cltd = ~(m_PENT | m_K6);
--const int x86_read_modify_write = ~m_PENT;
--const int x86_read_modify = ~(m_PENT | m_PPRO);
--const int x86_split_long_moves = m_PPRO;
--const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486 | m_ATHLON_K8;
--const int x86_fast_prefix = ~(m_PENT | m_486 | m_386);
--const int x86_single_stringop = m_386 | m_PENT4;
--const int x86_qimode_math = ~(0);
--const int x86_promote_qi_regs = 0;
--const int x86_himode_math = ~(m_PPRO);
--const int x86_promote_hi_regs = m_PPRO;
--const int x86_sub_esp_4 = m_ATHLON_K8 | m_PPRO | m_PENT4;
--const int x86_sub_esp_8 = m_ATHLON_K8 | m_PPRO | m_386 | m_486 | m_PENT4;
--const int x86_add_esp_4 = m_ATHLON_K8 | m_K6 | m_PENT4;
--const int x86_add_esp_8 = m_ATHLON_K8 | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
--const int x86_integer_DFmode_moves = ~(m_ATHLON_K8 | m_PENT4 | m_PPRO);
--const int x86_partial_reg_dependency = m_ATHLON_K8 | m_PENT4;
--const int x86_memory_mismatch_stall = m_ATHLON_K8 | m_PENT4;
--const int x86_accumulate_outgoing_args = m_ATHLON_K8 | m_PENT4 | m_PPRO;
--const int x86_prologue_using_move = m_ATHLON_K8 | m_PENT4 | m_PPRO;
--const int x86_epilogue_using_move = m_ATHLON_K8 | m_PENT4 | m_PPRO;
--const int x86_decompose_lea = m_PENT4;
--const int x86_shift1 = ~m_486;
--const int x86_arch_always_fancy_math_387 = m_PENT | m_PPRO | m_ATHLON_K8 | m_PENT4;
--const int x86_sse_partial_reg_dependency = m_PENT4 | m_PPRO;
--/* Set for machines where the type and dependencies are resolved on SSE register
--   parts instead of whole registers, so we may maintain just lower part of
--   scalar values in proper format leaving the upper part undefined.  */
--const int x86_sse_partial_regs = m_ATHLON_K8;
--/* Athlon optimizes partial-register FPS special case, thus avoiding the
--   need for extra instructions beforehand  */
--const int x86_sse_partial_regs_for_cvtsd2ss = 0;
--const int x86_sse_typeless_stores = m_ATHLON_K8;
--const int x86_sse_load0_by_pxor = m_PPRO | m_PENT4;
--const int x86_use_ffreep = m_ATHLON_K8;
--const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6;
--
--/* ??? HACK!  The following is a lie.  SSE can hold e.g. SImode, and
--   indeed *must* be able to hold SImode so that SSE2 shifts are able
--   to work right.  But this can result in some mighty surprising 
--   register allocation when building kernels.  Turning this off should
--   make us less likely to all-of-the-sudden select an SSE register.  */
--const int x86_inter_unit_moves = 0;  /* ~(m_ATHLON_K8) */
--
--const int x86_ext_80387_constants = m_K6 | m_ATHLON | m_PENT4 | m_PPRO;
--
--/* In case the average insn count for single function invocation is
--   lower than this constant, emit fast (but longer) prologue and
--   epilogue code.  */
--#define FAST_PROLOGUE_INSN_COUNT 20
--
--/* Names for 8 (low), 8 (high), and 16-bit registers, respectively.  */
--static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
--static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
--static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
--
--/* Array of the smallest class containing reg number REGNO, indexed by
--   REGNO.  Used by REGNO_REG_CLASS in i386.h.  */
--
--enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
--{
--  /* ax, dx, cx, bx */
--  AREG, DREG, CREG, BREG,
--  /* si, di, bp, sp */
--  SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
--  /* FP registers */
--  FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
--  FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
--  /* arg pointer */
--  NON_Q_REGS,
--  /* flags, fpsr, dirflag, frame */
--  NO_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
--  SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
--  SSE_REGS, SSE_REGS,
--  MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
--  MMX_REGS, MMX_REGS,
--  NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
--  NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
--  SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
--  SSE_REGS, SSE_REGS,
--};
--
--/* The "default" register map used in 32bit mode.  */
--
--int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
--{
--  0, 2, 1, 3, 6, 7, 4, 5,		/* general regs */
--  12, 13, 14, 15, 16, 17, 18, 19,	/* fp regs */
--  -1, -1, -1, -1, -1,			/* arg, flags, fpsr, dir, frame */
--  21, 22, 23, 24, 25, 26, 27, 28,	/* SSE */
--  29, 30, 31, 32, 33, 34, 35, 36,       /* MMX */
--  -1, -1, -1, -1, -1, -1, -1, -1,	/* extended integer registers */
--  -1, -1, -1, -1, -1, -1, -1, -1,	/* extended SSE registers */
--};
--
--static int const x86_64_int_parameter_registers[6] =
--{
--  5 /*RDI*/, 4 /*RSI*/, 1 /*RDX*/, 2 /*RCX*/,
--  FIRST_REX_INT_REG /*R8 */, FIRST_REX_INT_REG + 1 /*R9 */
--};
--
--static int const x86_64_int_return_registers[4] =
--{
--  0 /*RAX*/, 1 /*RDI*/, 5 /*RDI*/, 4 /*RSI*/
--};
--
--/* The "default" register map used in 64bit mode.  */
--int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
--{
--  0, 1, 2, 3, 4, 5, 6, 7,		/* general regs */
--  33, 34, 35, 36, 37, 38, 39, 40,	/* fp regs */
--  -1, -1, -1, -1, -1,			/* arg, flags, fpsr, dir, frame */
--  17, 18, 19, 20, 21, 22, 23, 24,	/* SSE */
--  41, 42, 43, 44, 45, 46, 47, 48,       /* MMX */
--  8,9,10,11,12,13,14,15,		/* extended integer registers */
--  25, 26, 27, 28, 29, 30, 31, 32,	/* extended SSE registers */
--};
--
--/* Define the register numbers to be used in Dwarf debugging information.
--   The SVR4 reference port C compiler uses the following register numbers
--   in its Dwarf output code:
--	0 for %eax (gcc regno = 0)
--	1 for %ecx (gcc regno = 2)
--	2 for %edx (gcc regno = 1)
--	3 for %ebx (gcc regno = 3)
--	4 for %esp (gcc regno = 7)
--	5 for %ebp (gcc regno = 6)
--	6 for %esi (gcc regno = 4)
--	7 for %edi (gcc regno = 5)
--   The following three DWARF register numbers are never generated by
--   the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
--   believes these numbers have these meanings.
--	8  for %eip    (no gcc equivalent)
--	9  for %eflags (gcc regno = 17)
--	10 for %trapno (no gcc equivalent)
--   It is not at all clear how we should number the FP stack registers
--   for the x86 architecture.  If the version of SDB on x86/svr4 were
--   a bit less brain dead with respect to floating-point then we would
--   have a precedent to follow with respect to DWARF register numbers
--   for x86 FP registers, but the SDB on x86/svr4 is so completely
--   broken with respect to FP registers that it is hardly worth thinking
--   of it as something to strive for compatibility with.
--   The version of x86/svr4 SDB I have at the moment does (partially)
--   seem to believe that DWARF register number 11 is associated with
--   the x86 register %st(0), but that's about all.  Higher DWARF
--   register numbers don't seem to be associated with anything in
--   particular, and even for DWARF regno 11, SDB only seems to under-
--   stand that it should say that a variable lives in %st(0) (when
--   asked via an `=' command) if we said it was in DWARF regno 11,
--   but SDB still prints garbage when asked for the value of the
--   variable in question (via a `/' command).
--   (Also note that the labels SDB prints for various FP stack regs
--   when doing an `x' command are all wrong.)
--   Note that these problems generally don't affect the native SVR4
--   C compiler because it doesn't allow the use of -O with -g and
--   because when it is *not* optimizing, it allocates a memory
--   location for each floating-point variable, and the memory
--   location is what gets described in the DWARF AT_location
--   attribute for the variable in question.
--   Regardless of the severe mental illness of the x86/svr4 SDB, we
--   do something sensible here and we use the following DWARF
--   register numbers.  Note that these are all stack-top-relative
--   numbers.
--	11 for %st(0) (gcc regno = 8)
--	12 for %st(1) (gcc regno = 9)
--	13 for %st(2) (gcc regno = 10)
--	14 for %st(3) (gcc regno = 11)
--	15 for %st(4) (gcc regno = 12)
--	16 for %st(5) (gcc regno = 13)
--	17 for %st(6) (gcc regno = 14)
--	18 for %st(7) (gcc regno = 15)
--*/
--int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
--{
--  0, 2, 1, 3, 6, 7, 5, 4,		/* general regs */
--  11, 12, 13, 14, 15, 16, 17, 18,	/* fp regs */
--  -1, 9, -1, -1, -1,			/* arg, flags, fpsr, dir, frame */
--  21, 22, 23, 24, 25, 26, 27, 28,	/* SSE registers */
--  29, 30, 31, 32, 33, 34, 35, 36,	/* MMX registers */
--  -1, -1, -1, -1, -1, -1, -1, -1,	/* extended integer registers */
--  -1, -1, -1, -1, -1, -1, -1, -1,	/* extended SSE registers */
--};
--
--/* Test and compare insns in i386.md store the information needed to
--   generate branch and scc insns here.  */
--
--rtx ix86_compare_op0 = NULL_RTX;
--rtx ix86_compare_op1 = NULL_RTX;
--
--#define MAX_386_STACK_LOCALS 3
--/* Size of the register save area.  */
--#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
--
--/* Define the structure for the machine field in struct function.  */
--
--struct stack_local_entry GTY(())
--{
--  unsigned short mode;
--  unsigned short n;
--  rtx rtl;
--  struct stack_local_entry *next;
--};
--
--/* Structure describing stack frame layout.
--   Stack grows downward:
--
--   [arguments]
--					      <- ARG_POINTER
--   saved pc
--
--   saved frame pointer if frame_pointer_needed
--					      <- HARD_FRAME_POINTER
--   [saved regs]
--
--   [padding1]          \
--		        )
--   [va_arg registers]  (
--		        > to_allocate	      <- FRAME_POINTER
--   [frame]	       (
--		        )
--   [padding2]	       /
--  */
--struct ix86_frame
--{
--  int nregs;
--  int padding1;
--  int va_arg_size;
--  HOST_WIDE_INT frame;
--  int padding2;
--  int outgoing_arguments_size;
--  int red_zone_size;
--
--  HOST_WIDE_INT to_allocate;
--  /* The offsets relative to ARG_POINTER.  */
--  HOST_WIDE_INT frame_pointer_offset;
--  HOST_WIDE_INT hard_frame_pointer_offset;
--  HOST_WIDE_INT stack_pointer_offset;
--
--  /* When save_regs_using_mov is set, emit prologue using
--     move instead of push instructions.  */
--  bool save_regs_using_mov;
--};
--
--/* Used to enable/disable debugging features.  */
--const char *ix86_debug_arg_string, *ix86_debug_addr_string;
--/* Code model option as passed by user.  */
--const char *ix86_cmodel_string;
--/* Parsed value.  */
--enum cmodel ix86_cmodel;
--/* Asm dialect.  */
--const char *ix86_asm_string;
--enum asm_dialect ix86_asm_dialect = ASM_ATT;
--/* TLS dialext.  */
--const char *ix86_tls_dialect_string;
--enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
--
--/* Which unit we are generating floating point math for.  */
--enum fpmath_unit ix86_fpmath;
--
--/* Which cpu are we scheduling for.  */
--enum processor_type ix86_tune;
--/* Which instruction set architecture to use.  */
--enum processor_type ix86_arch;
--
--/* Strings to hold which cpu and instruction set architecture  to use.  */
--const char *ix86_tune_string;		/* for -mtune=<xxx> */
--const char *ix86_arch_string;		/* for -march=<xxx> */
--const char *ix86_fpmath_string;		/* for -mfpmath=<xxx> */
--
--/* # of registers to use to pass arguments.  */
--const char *ix86_regparm_string;
--
--/* true if sse prefetch instruction is not NOOP.  */
--int x86_prefetch_sse;
--
--/* ix86_regparm_string as a number */
--int ix86_regparm;
--
--/* Alignment to use for loops and jumps:  */
--
--/* Power of two alignment for loops.  */
--const char *ix86_align_loops_string;
--
--/* Power of two alignment for non-loop jumps.  */
--const char *ix86_align_jumps_string;
--
--/* Power of two alignment for stack boundary in bytes.  */
--const char *ix86_preferred_stack_boundary_string;
--
--/* Preferred alignment for stack boundary in bits.  */
--int ix86_preferred_stack_boundary;
--
--/* Values 1-5: see jump.c */
--int ix86_branch_cost;
--const char *ix86_branch_cost_string;
--
--/* Power of two alignment for functions.  */
--const char *ix86_align_funcs_string;
--
--/* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
--static char internal_label_prefix[16];
--static int internal_label_prefix_len;
--
--static int local_symbolic_operand (rtx, enum machine_mode);
--static int tls_symbolic_operand_1 (rtx, enum tls_model);
--static void output_pic_addr_const (FILE *, rtx, int);
--static void put_condition_code (enum rtx_code, enum machine_mode,
--				int, int, FILE *);
--static const char *get_some_local_dynamic_name (void);
--static int get_some_local_dynamic_name_1 (rtx *, void *);
--static rtx maybe_get_pool_constant (rtx);
--static rtx ix86_expand_int_compare (enum rtx_code, rtx, rtx);
--static enum rtx_code ix86_prepare_fp_compare_args (enum rtx_code, rtx *,
--						   rtx *);
--static bool ix86_fixed_condition_code_regs (unsigned int *, unsigned int *);
--static enum machine_mode ix86_cc_modes_compatible (enum machine_mode,
--						   enum machine_mode);
--static rtx get_thread_pointer (int);
--static rtx legitimize_tls_address (rtx, enum tls_model, int);
--static void get_pc_thunk_name (char [32], unsigned int);
--static rtx gen_push (rtx);
--static int memory_address_length (rtx addr);
--static int ix86_flags_dependant (rtx, rtx, enum attr_type);
--static int ix86_agi_dependant (rtx, rtx, enum attr_type);
--static enum attr_ppro_uops ix86_safe_ppro_uops (rtx);
--static void ix86_dump_ppro_packet (FILE *);
--static void ix86_reorder_insn (rtx *, rtx *);
--static struct machine_function * ix86_init_machine_status (void);
--static int ix86_split_to_parts (rtx, rtx *, enum machine_mode);
--static int ix86_nsaved_regs (void);
--static void ix86_emit_save_regs (void);
--static void ix86_emit_save_regs_using_mov (rtx, HOST_WIDE_INT);
--static void ix86_emit_restore_regs_using_mov (rtx, HOST_WIDE_INT, int);
--static void ix86_output_function_epilogue (FILE *, HOST_WIDE_INT);
--static void ix86_sched_reorder_ppro (rtx *, rtx *);
--static HOST_WIDE_INT ix86_GOT_alias_set (void);
--static void ix86_adjust_counter (rtx, HOST_WIDE_INT);
--static rtx ix86_expand_aligntest (rtx, int);
--static void ix86_expand_strlensi_unroll_1 (rtx, rtx, rtx);
--static int ix86_issue_rate (void);
--static int ix86_adjust_cost (rtx, rtx, rtx, int);
--static void ix86_sched_init (FILE *, int, int);
--static int ix86_sched_reorder (FILE *, int, rtx *, int *, int);
--static int ix86_variable_issue (FILE *, int, rtx, int);
--static int ia32_use_dfa_pipeline_interface (void);
--static int ia32_multipass_dfa_lookahead (void);
--static void ix86_init_mmx_sse_builtins (void);
--static rtx x86_this_parameter (tree);
--static void x86_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
--				 HOST_WIDE_INT, tree);
--static bool x86_can_output_mi_thunk (tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
--static void x86_file_start (void);
--static void ix86_reorg (void);
--static bool ix86_expand_carry_flag_compare (enum rtx_code, rtx, rtx, rtx*);
--static tree ix86_build_builtin_va_list (void);
--
--struct ix86_address
--{
--  rtx base, index, disp;
--  HOST_WIDE_INT scale;
--  enum ix86_address_seg { SEG_DEFAULT, SEG_FS, SEG_GS } seg;
--};
--
--static int ix86_decompose_address (rtx, struct ix86_address *);
--static int ix86_address_cost (rtx);
--static bool ix86_cannot_force_const_mem (rtx);
--static rtx ix86_delegitimize_address (rtx);
--
--struct builtin_description;
--static rtx ix86_expand_sse_comi (const struct builtin_description *,
--				 tree, rtx);
--static rtx ix86_expand_sse_compare (const struct builtin_description *,
--				    tree, rtx);
--static rtx ix86_expand_unop1_builtin (enum insn_code, tree, rtx);
--static rtx ix86_expand_unop_builtin (enum insn_code, tree, rtx, int);
--static rtx ix86_expand_binop_builtin (enum insn_code, tree, rtx);
--static rtx ix86_expand_store_builtin (enum insn_code, tree);
--static rtx safe_vector_operand (rtx, enum machine_mode);
--static enum rtx_code ix86_fp_compare_code_to_integer (enum rtx_code);
--static void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *,
--				      enum rtx_code *, enum rtx_code *);
--static rtx ix86_expand_fp_compare (enum rtx_code, rtx, rtx, rtx, rtx *, rtx *);
--static int ix86_fp_comparison_arithmetics_cost (enum rtx_code code);
--static int ix86_fp_comparison_fcomi_cost (enum rtx_code code);
--static int ix86_fp_comparison_sahf_cost (enum rtx_code code);
--static int ix86_fp_comparison_cost (enum rtx_code code);
--static unsigned int ix86_select_alt_pic_regnum (void);
--static int ix86_save_reg (unsigned int, int);
--static void ix86_compute_frame_layout (struct ix86_frame *);
--static int ix86_comp_type_attributes (tree, tree);
--static int ix86_function_regparm (tree, tree);
--const struct attribute_spec ix86_attribute_table[];
--static bool ix86_function_ok_for_sibcall (tree, tree);
--static tree ix86_handle_cdecl_attribute (tree *, tree, tree, int, bool *);
--static tree ix86_handle_regparm_attribute (tree *, tree, tree, int, bool *);
--static int ix86_value_regno (enum machine_mode);
--static bool contains_128bit_aligned_vector_p (tree);
--static bool ix86_ms_bitfield_layout_p (tree);
--static tree ix86_handle_struct_attribute (tree *, tree, tree, int, bool *);
--static int extended_reg_mentioned_1 (rtx *, void *);
--static bool ix86_rtx_costs (rtx, int, int, int *);
--static int min_insn_size (rtx);
--static void k8_avoid_jump_misspredicts (void);
--
--#if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
--static void ix86_svr3_asm_out_constructor (rtx, int);
--#endif
--
--/* Register class used for passing given 64bit part of the argument.
--   These represent classes as documented by the PS ABI, with the exception
--   of SSESF, SSEDF classes, that are basically SSE class, just gcc will
--   use SF or DFmode move instead of DImode to avoid reformatting penalties.
--
--   Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
--   whenever possible (upper half does contain padding).
-- */
--enum x86_64_reg_class
--  {
--    X86_64_NO_CLASS,
--    X86_64_INTEGER_CLASS,
--    X86_64_INTEGERSI_CLASS,
--    X86_64_SSE_CLASS,
--    X86_64_SSESF_CLASS,
--    X86_64_SSEDF_CLASS,
--    X86_64_SSEUP_CLASS,
--    X86_64_X87_CLASS,
--    X86_64_X87UP_CLASS,
--    X86_64_MEMORY_CLASS
--  };
--static const char * const x86_64_reg_class_name[] =
--   {"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup", "x87", "x87up", "no"};
--
--#define MAX_CLASSES 4
--static int classify_argument (enum machine_mode, tree,
--			      enum x86_64_reg_class [MAX_CLASSES], int);
--static int examine_argument (enum machine_mode, tree, int, int *, int *);
--static rtx construct_container (enum machine_mode, tree, int, int, int,
--				const int *, int);
--static enum x86_64_reg_class merge_classes (enum x86_64_reg_class,
--					    enum x86_64_reg_class);
--
--/* Table of constants used by fldpi, fldln2, etc....  */
--static REAL_VALUE_TYPE ext_80387_constants_table [5];
--static bool ext_80387_constants_init = 0;
--static void init_ext_80387_constants (void);
--
--/* Initialize the GCC target structure.  */
--#undef TARGET_ATTRIBUTE_TABLE
--#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
--#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
--#  undef TARGET_MERGE_DECL_ATTRIBUTES
--#  define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
--#endif
--
--#undef TARGET_COMP_TYPE_ATTRIBUTES
--#define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
--
--#undef TARGET_INIT_BUILTINS
--#define TARGET_INIT_BUILTINS ix86_init_builtins
--
--#undef TARGET_EXPAND_BUILTIN
--#define TARGET_EXPAND_BUILTIN ix86_expand_builtin
--
--#undef TARGET_ASM_FUNCTION_EPILOGUE
--#define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
--
--#undef TARGET_ASM_OPEN_PAREN
--#define TARGET_ASM_OPEN_PAREN ""
--#undef TARGET_ASM_CLOSE_PAREN
--#define TARGET_ASM_CLOSE_PAREN ""
--
--#undef TARGET_ASM_ALIGNED_HI_OP
--#define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
--#undef TARGET_ASM_ALIGNED_SI_OP
--#define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
--#ifdef ASM_QUAD
--#undef TARGET_ASM_ALIGNED_DI_OP
--#define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
--#endif
--
--#undef TARGET_ASM_UNALIGNED_HI_OP
--#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
--#undef TARGET_ASM_UNALIGNED_SI_OP
--#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
--#undef TARGET_ASM_UNALIGNED_DI_OP
--#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
--
--#undef TARGET_SCHED_ADJUST_COST
--#define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
--#undef TARGET_SCHED_ISSUE_RATE
--#define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
--#undef TARGET_SCHED_VARIABLE_ISSUE
--#define TARGET_SCHED_VARIABLE_ISSUE ix86_variable_issue
--#undef TARGET_SCHED_INIT
--#define TARGET_SCHED_INIT ix86_sched_init
--#undef TARGET_SCHED_REORDER
--#define TARGET_SCHED_REORDER ix86_sched_reorder
--#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
--#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
--  ia32_use_dfa_pipeline_interface
--#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
--#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
--  ia32_multipass_dfa_lookahead
--
--#undef TARGET_FUNCTION_OK_FOR_SIBCALL
--#define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
--
--#ifdef HAVE_AS_TLS
--#undef TARGET_HAVE_TLS
--#define TARGET_HAVE_TLS true
--#endif
--#undef TARGET_CANNOT_FORCE_CONST_MEM
--#define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
--
--#undef TARGET_DELEGITIMIZE_ADDRESS
--#define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
--
--#undef TARGET_MS_BITFIELD_LAYOUT_P
--#define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
--
--#undef TARGET_ASM_OUTPUT_MI_THUNK
--#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
--#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
--#define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
--
--#undef TARGET_ASM_FILE_START
--#define TARGET_ASM_FILE_START x86_file_start
--
--#undef TARGET_RTX_COSTS
--#define TARGET_RTX_COSTS ix86_rtx_costs
--#undef TARGET_ADDRESS_COST
--#define TARGET_ADDRESS_COST ix86_address_cost
--
--#undef TARGET_FIXED_CONDITION_CODE_REGS
--#define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
--#undef TARGET_CC_MODES_COMPATIBLE
--#define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
--
--#undef TARGET_MACHINE_DEPENDENT_REORG
--#define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
--
--#undef TARGET_BUILD_BUILTIN_VA_LIST
--#define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
--
--struct gcc_target targetm = TARGET_INITIALIZER;
--
--/* The svr4 ABI for the i386 says that records and unions are returned
--   in memory.  */
--#ifndef DEFAULT_PCC_STRUCT_RETURN
--#define DEFAULT_PCC_STRUCT_RETURN 1
--#endif
--
--/* Sometimes certain combinations of command options do not make
--   sense on a particular target machine.  You can define a macro
--   `OVERRIDE_OPTIONS' to take account of this.  This macro, if
--   defined, is executed once just after all the command options have
--   been parsed.
--
--   Don't use this macro to turn on various extra optimizations for
--   `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
--
--void
--override_options (void)
--{
--  int i;
--  /* Comes from final.c -- no real reason to change it.  */
--#define MAX_CODE_ALIGN 16
--
--  static struct ptt
--    {
--      const struct processor_costs *cost;	/* Processor costs */
--      const int target_enable;			/* Target flags to enable.  */
--      const int target_disable;			/* Target flags to disable.  */
--      const int align_loop;			/* Default alignments.  */
--      const int align_loop_max_skip;
--      const int align_jump;
--      const int align_jump_max_skip;
--      const int align_func;
--    }
--  const processor_target_table[PROCESSOR_max] =
--    {
--      {&i386_cost, 0, 0, 4, 3, 4, 3, 4},
--      {&i486_cost, 0, 0, 16, 15, 16, 15, 16},
--      {&pentium_cost, 0, 0, 16, 7, 16, 7, 16},
--      {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16},
--      {&k6_cost, 0, 0, 32, 7, 32, 7, 32},
--      {&athlon_cost, 0, 0, 16, 7, 16, 7, 16},
--      {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0},
--      {&k8_cost, 0, 0, 16, 7, 16, 7, 16}
--    };
--
--  static const char * const cpu_names[] = TARGET_CPU_DEFAULT_NAMES;
--  static struct pta
--    {
--      const char *const name;		/* processor name or nickname.  */
--      const enum processor_type processor;
--      const enum pta_flags
--	{
--	  PTA_SSE = 1,
--	  PTA_SSE2 = 2,
--	  PTA_SSE3 = 4,
--	  PTA_MMX = 8,
--	  PTA_PREFETCH_SSE = 16,
--	  PTA_3DNOW = 32,
--	  PTA_3DNOW_A = 64,
--	  PTA_64BIT = 128
--	} flags;
--    }
--  const processor_alias_table[] =
--    {
--      {"i386", PROCESSOR_I386, 0},
--      {"i486", PROCESSOR_I486, 0},
--      {"i586", PROCESSOR_PENTIUM, 0},
--      {"pentium", PROCESSOR_PENTIUM, 0},
--      {"pentium-mmx", PROCESSOR_PENTIUM, PTA_MMX},
--      {"winchip-c6", PROCESSOR_I486, PTA_MMX},
--      {"winchip2", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
--      {"c3", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
--      {"c3-2", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_PREFETCH_SSE | PTA_SSE},
--      {"i686", PROCESSOR_PENTIUMPRO, 0},
--      {"pentiumpro", PROCESSOR_PENTIUMPRO, 0},
--      {"pentium2", PROCESSOR_PENTIUMPRO, PTA_MMX},
--      {"pentium3", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE},
--      {"pentium3m", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE},
--      {"pentium-m", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE | PTA_SSE2},
--      {"pentium4", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2
--				       | PTA_MMX | PTA_PREFETCH_SSE},
--      {"pentium4m", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2
--				        | PTA_MMX | PTA_PREFETCH_SSE},
--      {"prescott", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2 | PTA_SSE3
--				        | PTA_MMX | PTA_PREFETCH_SSE},
--      {"nocona", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_64BIT
--				     | PTA_MMX | PTA_PREFETCH_SSE},
--      {"k6", PROCESSOR_K6, PTA_MMX},
--      {"k6-2", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
--      {"k6-3", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
--      {"athlon", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
--				   | PTA_3DNOW_A},
--      {"athlon-tbird", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE
--					 | PTA_3DNOW | PTA_3DNOW_A},
--      {"athlon-4", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
--				    | PTA_3DNOW_A | PTA_SSE},
--      {"athlon-xp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
--				      | PTA_3DNOW_A | PTA_SSE},
--      {"athlon-mp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
--				      | PTA_3DNOW_A | PTA_SSE},
--      {"x86-64", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_64BIT
--			       | PTA_SSE | PTA_SSE2 },
--      {"k8", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
--				      | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
--      {"opteron", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
--				      | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
--      {"athlon64", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
--				      | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
--      {"athlon-fx", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
--				      | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
--    };
--
--  int const pta_size = ARRAY_SIZE (processor_alias_table);
--
--  /* Set the default values for switches whose default depends on TARGET_64BIT
--     in case they weren't overwritten by command line options.  */
--  if (TARGET_64BIT)
--    {
--      if (flag_omit_frame_pointer == 2)
--	flag_omit_frame_pointer = 1;
--      if (flag_asynchronous_unwind_tables == 2)
--	flag_asynchronous_unwind_tables = 1;
--      if (flag_pcc_struct_return == 2)
--	flag_pcc_struct_return = 0;
--    }
--  else
--    {
--      if (flag_omit_frame_pointer == 2)
--	flag_omit_frame_pointer = 0;
--      if (flag_asynchronous_unwind_tables == 2)
--	flag_asynchronous_unwind_tables = 0;
--      if (flag_pcc_struct_return == 2)
--	flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
--    }
--
--#ifdef SUBTARGET_OVERRIDE_OPTIONS
--  SUBTARGET_OVERRIDE_OPTIONS;
--#endif
--
--  if (!ix86_tune_string && ix86_arch_string)
--    ix86_tune_string = ix86_arch_string;
--  if (!ix86_tune_string)
--    ix86_tune_string = cpu_names [TARGET_CPU_DEFAULT];
--  if (!ix86_arch_string)
--    ix86_arch_string = TARGET_64BIT ? "x86-64" : "i386";
--
--  if (ix86_cmodel_string != 0)
--    {
--      if (!strcmp (ix86_cmodel_string, "small"))
--	ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
--      else if (flag_pic)
--	sorry ("code model %s not supported in PIC mode", ix86_cmodel_string);
--      else if (!strcmp (ix86_cmodel_string, "32"))
--	ix86_cmodel = CM_32;
--      else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
--	ix86_cmodel = CM_KERNEL;
--      else if (!strcmp (ix86_cmodel_string, "medium") && !flag_pic)
--	ix86_cmodel = CM_MEDIUM;
--      else if (!strcmp (ix86_cmodel_string, "large") && !flag_pic)
--	ix86_cmodel = CM_LARGE;
--      else
--	error ("bad value (%s) for -mcmodel= switch", ix86_cmodel_string);
--    }
--  else
--    {
--      ix86_cmodel = CM_32;
--      if (TARGET_64BIT)
--	ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
--    }
--  if (ix86_asm_string != 0)
--    {
--      if (!strcmp (ix86_asm_string, "intel"))
--	ix86_asm_dialect = ASM_INTEL;
--      else if (!strcmp (ix86_asm_string, "att"))
--	ix86_asm_dialect = ASM_ATT;
--      else
--	error ("bad value (%s) for -masm= switch", ix86_asm_string);
--    }
--  if ((TARGET_64BIT == 0) != (ix86_cmodel == CM_32))
--    error ("code model `%s' not supported in the %s bit mode",
--	   ix86_cmodel_string, TARGET_64BIT ? "64" : "32");
--  if (ix86_cmodel == CM_LARGE)
--    sorry ("code model `large' not supported yet");
--  if ((TARGET_64BIT != 0) != ((target_flags & MASK_64BIT) != 0))
--    sorry ("%i-bit mode not compiled in",
--	   (target_flags & MASK_64BIT) ? 64 : 32);
--
--  for (i = 0; i < pta_size; i++)
--    if (! strcmp (ix86_arch_string, processor_alias_table[i].name))
--      {
--	ix86_arch = processor_alias_table[i].processor;
--	/* Default cpu tuning to the architecture.  */
--	ix86_tune = ix86_arch;
--	if (processor_alias_table[i].flags & PTA_MMX
--	    && !(target_flags_explicit & MASK_MMX))
--	  target_flags |= MASK_MMX;
--	if (processor_alias_table[i].flags & PTA_3DNOW
--	    && !(target_flags_explicit & MASK_3DNOW))
--	  target_flags |= MASK_3DNOW;
--	if (processor_alias_table[i].flags & PTA_3DNOW_A
--	    && !(target_flags_explicit & MASK_3DNOW_A))
--	  target_flags |= MASK_3DNOW_A;
--	if (processor_alias_table[i].flags & PTA_SSE
--	    && !(target_flags_explicit & MASK_SSE))
--	  target_flags |= MASK_SSE;
--	if (processor_alias_table[i].flags & PTA_SSE2
--	    && !(target_flags_explicit & MASK_SSE2))
--	  target_flags |= MASK_SSE2;
--	if (processor_alias_table[i].flags & PTA_SSE3
--	    && !(target_flags_explicit & MASK_SSE3))
--	  target_flags |= MASK_SSE3;
--	if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
--	  x86_prefetch_sse = true;
--	if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
--	  error ("CPU you selected does not support x86-64 instruction set");
--	break;
--      }
--
--  if (i == pta_size)
--    error ("bad value (%s) for -march= switch", ix86_arch_string);
--
--  for (i = 0; i < pta_size; i++)
--    if (! strcmp (ix86_tune_string, processor_alias_table[i].name))
--      {
--	ix86_tune = processor_alias_table[i].processor;
--	if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
--	  error ("CPU you selected does not support x86-64 instruction set");
--
--	/* Intel CPUs have always interpreted SSE prefetch instructions as
--	   NOPs; so, we can enable SSE prefetch instructions even when
--	   -mtune (rather than -march) points us to a processor that has them.
--	   However, the VIA C3 gives a SIGILL, so we only do that for i686 and
--	   higher processors.  */
--	if (TARGET_CMOVE && (processor_alias_table[i].flags & PTA_PREFETCH_SSE))
--	  x86_prefetch_sse = true;
--	break;
--      }
--  if (i == pta_size)
--    error ("bad value (%s) for -mtune= switch", ix86_tune_string);
--
--  if (optimize_size)
--    ix86_cost = &size_cost;
--  else
--    ix86_cost = processor_target_table[ix86_tune].cost;
--  target_flags |= processor_target_table[ix86_tune].target_enable;
--  target_flags &= ~processor_target_table[ix86_tune].target_disable;
--
--  /* Arrange to set up i386_stack_locals for all functions.  */
--  init_machine_status = ix86_init_machine_status;
--
--  /* Validate -mregparm= value.  */
--  if (ix86_regparm_string)
--    {
--      i = atoi (ix86_regparm_string);
--      if (i < 0 || i > REGPARM_MAX)
--	error ("-mregparm=%d is not between 0 and %d", i, REGPARM_MAX);
--      else
--	ix86_regparm = i;
--    }
--  else
--   if (TARGET_64BIT)
--     ix86_regparm = REGPARM_MAX;
--
--  /* If the user has provided any of the -malign-* options,
--     warn and use that value only if -falign-* is not set.
--     Remove this code in GCC 3.2 or later.  */
--  if (ix86_align_loops_string)
--    {
--      warning ("-malign-loops is obsolete, use -falign-loops");
--      if (align_loops == 0)
--	{
--	  i = atoi (ix86_align_loops_string);
--	  if (i < 0 || i > MAX_CODE_ALIGN)
--	    error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
--	  else
--	    align_loops = 1 << i;
--	}
--    }
--
--  if (ix86_align_jumps_string)
--    {
--      warning ("-malign-jumps is obsolete, use -falign-jumps");
--      if (align_jumps == 0)
--	{
--	  i = atoi (ix86_align_jumps_string);
--	  if (i < 0 || i > MAX_CODE_ALIGN)
--	    error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
--	  else
--	    align_jumps = 1 << i;
--	}
--    }
--
--  if (ix86_align_funcs_string)
--    {
--      warning ("-malign-functions is obsolete, use -falign-functions");
--      if (align_functions == 0)
--	{
--	  i = atoi (ix86_align_funcs_string);
--	  if (i < 0 || i > MAX_CODE_ALIGN)
--	    error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
--	  else
--	    align_functions = 1 << i;
--	}
--    }
--
--  /* Default align_* from the processor table.  */
--  if (align_loops == 0)
--    {
--      align_loops = processor_target_table[ix86_tune].align_loop;
--      align_loops_max_skip = processor_target_table[ix86_tune].align_loop_max_skip;
--    }
--  if (align_jumps == 0)
--    {
--      align_jumps = processor_target_table[ix86_tune].align_jump;
--      align_jumps_max_skip = processor_target_table[ix86_tune].align_jump_max_skip;
--    }
--  if (align_functions == 0)
--    {
--      align_functions = processor_target_table[ix86_tune].align_func;
--    }
--
--  /* Validate -mpreferred-stack-boundary= value, or provide default.
--     The default of 128 bits is for Pentium III's SSE __m128, but we
--     don't want additional code to keep the stack aligned when
--     optimizing for code size.  */
--  ix86_preferred_stack_boundary = (optimize_size
--				   ? TARGET_64BIT ? 128 : 32
--				   : 128);
--  if (ix86_preferred_stack_boundary_string)
--    {
--      i = atoi (ix86_preferred_stack_boundary_string);
--      if (i < (TARGET_64BIT ? 4 : 2) || i > 12)
--	error ("-mpreferred-stack-boundary=%d is not between %d and 12", i,
--	       TARGET_64BIT ? 4 : 2);
--      else
--	ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
--    }
--
--  /* Validate -mbranch-cost= value, or provide default.  */
--  ix86_branch_cost = processor_target_table[ix86_tune].cost->branch_cost;
--  if (ix86_branch_cost_string)
--    {
--      i = atoi (ix86_branch_cost_string);
--      if (i < 0 || i > 5)
--	error ("-mbranch-cost=%d is not between 0 and 5", i);
--      else
--	ix86_branch_cost = i;
--    }
--
--  if (ix86_tls_dialect_string)
--    {
--      if (strcmp (ix86_tls_dialect_string, "gnu") == 0)
--	ix86_tls_dialect = TLS_DIALECT_GNU;
--      else if (strcmp (ix86_tls_dialect_string, "sun") == 0)
--	ix86_tls_dialect = TLS_DIALECT_SUN;
--      else
--	error ("bad value (%s) for -mtls-dialect= switch",
--	       ix86_tls_dialect_string);
--    }
--
--  /* Keep nonleaf frame pointers.  */
--  if (TARGET_OMIT_LEAF_FRAME_POINTER)
--    flag_omit_frame_pointer = 1;
--
--  /* If we're doing fast math, we don't care about comparison order
--     wrt NaNs.  This lets us use a shorter comparison sequence.  */
--  if (flag_unsafe_math_optimizations)
--    target_flags &= ~MASK_IEEE_FP;
--
--  /* If the architecture always has an FPU, turn off NO_FANCY_MATH_387,
--     since the insns won't need emulation.  */
--  if (x86_arch_always_fancy_math_387 & (1 << ix86_arch))
--    target_flags &= ~MASK_NO_FANCY_MATH_387;
--
--  /* Turn on SSE2 builtins for -msse3.  */
--  if (TARGET_SSE3)
--    target_flags |= MASK_SSE2;
--
--  /* Turn on SSE builtins for -msse2.  */
--  if (TARGET_SSE2)
--    target_flags |= MASK_SSE;
--
--  if (TARGET_64BIT)
--    {
--      if (TARGET_ALIGN_DOUBLE)
--	error ("-malign-double makes no sense in the 64bit mode");
--      if (TARGET_RTD)
--	error ("-mrtd calling convention not supported in the 64bit mode");
--      /* Enable by default the SSE and MMX builtins.  */
--      target_flags |= (MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE);
--      ix86_fpmath = FPMATH_SSE;
--     }
--  else
--    {
--      ix86_fpmath = FPMATH_387;
--      /* i386 ABI does not specify red zone.  It still makes sense to use it
--         when programmer takes care to stack from being destroyed.  */
--      if (!(target_flags_explicit & MASK_NO_RED_ZONE))
--        target_flags |= MASK_NO_RED_ZONE;
--    }
--
--  if (ix86_fpmath_string != 0)
--    {
--      if (! strcmp (ix86_fpmath_string, "387"))
--	ix86_fpmath = FPMATH_387;
--      else if (! strcmp (ix86_fpmath_string, "sse"))
--	{
--	  if (!TARGET_SSE)
--	    {
--	      warning ("SSE instruction set disabled, using 387 arithmetics");
--	      ix86_fpmath = FPMATH_387;
--	    }
--	  else
--	    ix86_fpmath = FPMATH_SSE;
--	}
--      else if (! strcmp (ix86_fpmath_string, "387,sse")
--	       || ! strcmp (ix86_fpmath_string, "sse,387"))
--	{
--	  if (!TARGET_SSE)
--	    {
--	      warning ("SSE instruction set disabled, using 387 arithmetics");
--	      ix86_fpmath = FPMATH_387;
--	    }
--	  else if (!TARGET_80387)
--	    {
--	      warning ("387 instruction set disabled, using SSE arithmetics");
--	      ix86_fpmath = FPMATH_SSE;
--	    }
--	  else
--	    ix86_fpmath = FPMATH_SSE | FPMATH_387;
--	}
--      else
--	error ("bad value (%s) for -mfpmath= switch", ix86_fpmath_string);
--    }
--
--  /* It makes no sense to ask for just SSE builtins, so MMX is also turned
--     on by -msse.  */
--  if (TARGET_SSE)
--    {
--      target_flags |= MASK_MMX;
--      x86_prefetch_sse = true;
--    }
--
--  /* If it has 3DNow! it also has MMX so MMX is also turned on by -m3dnow */
--  if (TARGET_3DNOW)
--    {
--      target_flags |= MASK_MMX;
--      /* If we are targeting the Athlon architecture, enable the 3Dnow/MMX
--	 extensions it adds.  */
--      if (x86_3dnow_a & (1 << ix86_arch))
--	target_flags |= MASK_3DNOW_A;
--    }
--  if ((x86_accumulate_outgoing_args & TUNEMASK)
--      && !(target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
--      && !optimize_size)
--    target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
--
--  /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix.  */
--  {
--    char *p;
--    ASM_GENERATE_INTERNAL_LABEL (internal_label_prefix, "LX", 0);
--    p = strchr (internal_label_prefix, 'X');
--    internal_label_prefix_len = p - internal_label_prefix;
--    *p = '\0';
--  }
--}
--
--void
--optimization_options (int level, int size ATTRIBUTE_UNUSED)
--{
--  /* For -O2 and beyond, turn off -fschedule-insns by default.  It tends to
--     make the problem with not enough registers even worse.  */
--#ifdef INSN_SCHEDULING
--  if (level > 1)
--    flag_schedule_insns = 0;
--#endif
--
--  /* The default values of these switches depend on the TARGET_64BIT
--     that is not known at this moment.  Mark these values with 2 and
--     let user the to override these.  In case there is no command line option
--     specifying them, we will set the defaults in override_options.  */
--  if (optimize >= 1)
--    flag_omit_frame_pointer = 2;
--  flag_pcc_struct_return = 2;
--  flag_asynchronous_unwind_tables = 2;
--}
--
--/* Table of valid machine attributes.  */
--const struct attribute_spec ix86_attribute_table[] =
--{
--  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
--  /* Stdcall attribute says callee is responsible for popping arguments
--     if they are not variable.  */
--  { "stdcall",   0, 0, false, true,  true,  ix86_handle_cdecl_attribute },
--  /* Fastcall attribute says callee is responsible for popping arguments
--     if they are not variable.  */
--  { "fastcall",  0, 0, false, true,  true,  ix86_handle_cdecl_attribute },
--  /* Cdecl attribute says the callee is a normal C declaration */
--  { "cdecl",     0, 0, false, true,  true,  ix86_handle_cdecl_attribute },
--  /* Regparm attribute specifies how many integer arguments are to be
--     passed in registers.  */
--  { "regparm",   1, 1, false, true,  true,  ix86_handle_regparm_attribute },
--#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
--  { "dllimport", 0, 0, false, false, false, ix86_handle_dll_attribute },
--  { "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute },
--  { "shared",    0, 0, true,  false, false, ix86_handle_shared_attribute },
--#endif
--  { "ms_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute },
--  { "gcc_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute },
--  { NULL,        0, 0, false, false, false, NULL }
--};
--
--/* Decide whether we can make a sibling call to a function.  DECL is the
--   declaration of the function being targeted by the call and EXP is the
--   CALL_EXPR representing the call.  */
--
--static bool
--ix86_function_ok_for_sibcall (tree decl, tree exp)
--{
--  /* If we are generating position-independent code, we cannot sibcall
--     optimize any indirect call, or a direct call to a global function,
--     as the PLT requires %ebx be live.  */
--  if (!TARGET_64BIT && flag_pic && (!decl || TREE_PUBLIC (decl)))
--    return false;
--
--  /* If we are returning floats on the 80387 register stack, we cannot
--     make a sibcall from a function that doesn't return a float to a
--     function that does or, conversely, from a function that does return
--     a float to a function that doesn't; the necessary stack adjustment
--     would not be executed.  */
--  if (STACK_REG_P (ix86_function_value (TREE_TYPE (exp)))
--      != STACK_REG_P (ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)))))
--    return false;
--
--  /* If this call is indirect, we'll need to be able to use a call-clobbered
--     register for the address of the target function.  Make sure that all
--     such registers are not used for passing parameters.  */
--  if (!decl && !TARGET_64BIT)
--    {
--      tree type;
--
--      /* We're looking at the CALL_EXPR, we need the type of the function.  */
--      type = TREE_OPERAND (exp, 0);		/* pointer expression */
--      type = TREE_TYPE (type);			/* pointer type */
--      type = TREE_TYPE (type);			/* function type */
--
--      if (ix86_function_regparm (type, NULL) >= 3)
--	{
--	  /* ??? Need to count the actual number of registers to be used,
--	     not the possible number of registers.  Fix later.  */
--	  return false;
--	}
--    }
--
--  /* Otherwise okay.  That also includes certain types of indirect calls.  */
--  return true;
--}
--
--/* Handle a "cdecl", "stdcall", or "fastcall" attribute;
--   arguments as in struct attribute_spec.handler.  */
--static tree
--ix86_handle_cdecl_attribute (tree *node, tree name,
--			     tree args ATTRIBUTE_UNUSED,
--			     int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
--{
--  if (TREE_CODE (*node) != FUNCTION_TYPE
--      && TREE_CODE (*node) != METHOD_TYPE
--      && TREE_CODE (*node) != FIELD_DECL
--      && TREE_CODE (*node) != TYPE_DECL)
--    {
--      warning ("`%s' attribute only applies to functions",
--	       IDENTIFIER_POINTER (name));
--      *no_add_attrs = true;
--    }
--  else
--    {
--      if (is_attribute_p ("fastcall", name))
--        {
--          if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
--            {
--              error ("fastcall and stdcall attributes are not compatible");
--            }
--           else if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
--            {
--              error ("fastcall and regparm attributes are not compatible");
--            }
--        }
--      else if (is_attribute_p ("stdcall", name))
--        {
--          if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
--            {
--              error ("fastcall and stdcall attributes are not compatible");
--            }
--        }
--    }
--
--  if (TARGET_64BIT)
--    {
--      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
--      *no_add_attrs = true;
--    }
--
--  return NULL_TREE;
--}
--
--/* Handle a "regparm" attribute;
--   arguments as in struct attribute_spec.handler.  */
--static tree
--ix86_handle_regparm_attribute (tree *node, tree name, tree args,
--			       int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
--{
--  if (TREE_CODE (*node) != FUNCTION_TYPE
--      && TREE_CODE (*node) != METHOD_TYPE
--      && TREE_CODE (*node) != FIELD_DECL
--      && TREE_CODE (*node) != TYPE_DECL)
--    {
--      warning ("`%s' attribute only applies to functions",
--	       IDENTIFIER_POINTER (name));
--      *no_add_attrs = true;
--    }
--  else
--    {
--      tree cst;
--
--      cst = TREE_VALUE (args);
--      if (TREE_CODE (cst) != INTEGER_CST)
--	{
--	  warning ("`%s' attribute requires an integer constant argument",
--		   IDENTIFIER_POINTER (name));
--	  *no_add_attrs = true;
--	}
--      else if (compare_tree_int (cst, REGPARM_MAX) > 0)
--	{
--	  warning ("argument to `%s' attribute larger than %d",
--		   IDENTIFIER_POINTER (name), REGPARM_MAX);
--	  *no_add_attrs = true;
--	}
--
--      if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
--	{
--	  error ("fastcall and regparm attributes are not compatible");
--	}
--    }
--
--  return NULL_TREE;
--}
--
--/* Return 0 if the attributes for two types are incompatible, 1 if they
--   are compatible, and 2 if they are nearly compatible (which causes a
--   warning to be generated).  */
--
--static int
--ix86_comp_type_attributes (tree type1, tree type2)
--{
--  /* Check for mismatch of non-default calling convention.  */
--  const char *const rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
--
--  if (TREE_CODE (type1) != FUNCTION_TYPE)
--    return 1;
--
--  /*  Check for mismatched fastcall types */
--  if (!lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type1))
--      != !lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type2)))
--    return 0;
--
--  /* Check for mismatched return types (cdecl vs stdcall).  */
--  if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
--      != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
--    return 0;
--  if (ix86_function_regparm (type1, NULL)
--      != ix86_function_regparm (type2, NULL))
--    return 0;
--  return 1;
--}
--
--/* Return the regparm value for a fuctio with the indicated TYPE and DECL.
--   DECL may be NULL when calling function indirectly
--   or considering a libcall.  */
--
--static int
--ix86_function_regparm (tree type, tree decl)
--{
--  tree attr;
--  int regparm = ix86_regparm;
--  bool user_convention = false;
--
--  if (!TARGET_64BIT)
--    {
--      attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
--      if (attr)
--	{
--	  regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
--	  user_convention = true;
--	}
--
--      if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
--	{
--	  regparm = 2;
--	  user_convention = true;
--	}
--
--      /* Use register calling convention for local functions when possible.  */
--      if (!TARGET_64BIT && !user_convention && decl
--	  && flag_unit_at_a_time && !profile_flag)
--	{
--	  struct cgraph_local_info *i = cgraph_local_info (decl);
--	  if (i && i->local)
--	    {
--	      /* We can't use regparm(3) for nested functions as these use
--		 static chain pointer in third argument.  */
--	      if (DECL_CONTEXT (decl) && !DECL_NO_STATIC_CHAIN (decl))
--		regparm = 2;
--	      else
--		regparm = 3;
--	    }
--	}
--    }
--  return regparm;
--}
--
--/* Return true if EAX is live at the start of the function.  Used by 
--   ix86_expand_prologue to determine if we need special help before
--   calling allocate_stack_worker.  */
--
--static bool
--ix86_eax_live_at_start_p (void)
--{
--  /* Cheat.  Don't bother working forward from ix86_function_regparm
--     to the function type to whether an actual argument is located in
--     eax.  Instead just look at cfg info, which is still close enough
--     to correct at this point.  This gives false positives for broken
--     functions that might use uninitialized data that happens to be
--     allocated in eax, but who cares?  */
--  return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, 0);
--}
--
--/* Value is the number of bytes of arguments automatically
--   popped when returning from a subroutine call.
--   FUNDECL is the declaration node of the function (as a tree),
--   FUNTYPE is the data type of the function (as a tree),
--   or for a library call it is an identifier node for the subroutine name.
--   SIZE is the number of bytes of arguments passed on the stack.
--
--   On the 80386, the RTD insn may be used to pop them if the number
--     of args is fixed, but if the number is variable then the caller
--     must pop them all.  RTD can't be used for library calls now
--     because the library is compiled with the Unix compiler.
--   Use of RTD is a selectable option, since it is incompatible with
--   standard Unix calling sequences.  If the option is not selected,
--   the caller must always pop the args.
--
--   The attribute stdcall is equivalent to RTD on a per module basis.  */
--
--int
--ix86_return_pops_args (tree fundecl, tree funtype, int size)
--{
--  int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
--
--  /* Cdecl functions override -mrtd, and never pop the stack.  */
--  if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
--
--    /* Stdcall and fastcall functions will pop the stack if not
--       variable args.  */
--    if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))
--        || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))
--      rtd = 1;
--
--    if (rtd
--        && (TYPE_ARG_TYPES (funtype) == NULL_TREE
--	    || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype)))
--		== void_type_node)))
--      return size;
--  }
--
--  /* Lose any fake structure return argument if it is passed on the stack.  */
--  if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
--      && !TARGET_64BIT)
--    {
--      int nregs = ix86_function_regparm (funtype, fundecl);
--
--      if (!nregs)
--	return GET_MODE_SIZE (Pmode);
--    }
--
--  return 0;
--}
--
--/* Argument support functions.  */
--
--/* Return true when register may be used to pass function parameters.  */
--bool
--ix86_function_arg_regno_p (int regno)
--{
--  int i;
--  if (!TARGET_64BIT)
--    return (regno < REGPARM_MAX
--	    || (TARGET_SSE && SSE_REGNO_P (regno) && !fixed_regs[regno]));
--  if (SSE_REGNO_P (regno) && TARGET_SSE)
--    return true;
--  /* RAX is used as hidden argument to va_arg functions.  */
--  if (!regno)
--    return true;
--  for (i = 0; i < REGPARM_MAX; i++)
--    if (regno == x86_64_int_parameter_registers[i])
--      return true;
--  return false;
--}
--
--/* 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.  */
--
--void
--init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
--		      tree fntype,	/* tree ptr for function decl */
--		      rtx libname,	/* SYMBOL_REF of library name or 0 */
--		      tree fndecl)
--{
--  static CUMULATIVE_ARGS zero_cum;
--  tree param, next_param;
--
--  if (TARGET_DEBUG_ARG)
--    {
--      fprintf (stderr, "\ninit_cumulative_args (");
--      if (fntype)
--	fprintf (stderr, "fntype code = %s, ret code = %s",
--		 tree_code_name[(int) TREE_CODE (fntype)],
--		 tree_code_name[(int) TREE_CODE (TREE_TYPE (fntype))]);
--      else
--	fprintf (stderr, "no fntype");
--
--      if (libname)
--	fprintf (stderr, ", libname = %s", XSTR (libname, 0));
--    }
--
--  *cum = zero_cum;
--
--  /* Set up the number of registers to use for passing arguments.  */
--  if (fntype)
--    cum->nregs = ix86_function_regparm (fntype, fndecl);
--  else
--    cum->nregs = ix86_regparm;
--  cum->sse_nregs = SSE_REGPARM_MAX;
--  cum->mmx_nregs = MMX_REGPARM_MAX;
--  cum->warn_sse = true;
--  cum->warn_mmx = true;
--  cum->maybe_vaarg = false;
--
--  /* Use ecx and edx registers if function has fastcall attribute */
--  if (fntype && !TARGET_64BIT)
--    {
--      if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)))
--	{
--	  cum->nregs = 2;
--	  cum->fastcall = 1;
--	}
--    }
--
--
--  /* Determine if this function has variable arguments.  This is
--     indicated by the last argument being 'void_type_mode' if there
--     are no variable arguments.  If there are variable arguments, then
--     we won't pass anything in registers */
--
--  if (cum->nregs || !TARGET_MMX || !TARGET_SSE)
--    {
--      for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
--	   param != 0; param = next_param)
--	{
--	  next_param = TREE_CHAIN (param);
--	  if (next_param == 0 && TREE_VALUE (param) != void_type_node)
--	    {
--	      if (!TARGET_64BIT)
--		{
--		  cum->nregs = 0;
--		  cum->sse_nregs = 0;
--		  cum->mmx_nregs = 0;
--		  cum->warn_sse = 0;
--		  cum->warn_mmx = 0;
--		  cum->fastcall = 0;
--		}
--	      cum->maybe_vaarg = true;
--	    }
--	}
--    }
--  if ((!fntype && !libname)
--      || (fntype && !TYPE_ARG_TYPES (fntype)))
--    cum->maybe_vaarg = 1;
--
--  if (TARGET_DEBUG_ARG)
--    fprintf (stderr, ", nregs=%d )\n", cum->nregs);
--
--  return;
--}
--
--/* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
--   of this code is to classify each 8bytes of incoming argument by the register
--   class and assign registers accordingly.  */
--
--/* Return the union class of CLASS1 and CLASS2.
--   See the x86-64 PS ABI for details.  */
--
--static enum x86_64_reg_class
--merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
--{
--  /* Rule #1: If both classes are equal, this is the resulting class.  */
--  if (class1 == class2)
--    return class1;
--
--  /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
--     the other class.  */
--  if (class1 == X86_64_NO_CLASS)
--    return class2;
--  if (class2 == X86_64_NO_CLASS)
--    return class1;
--
--  /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
--  if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
--    return X86_64_MEMORY_CLASS;
--
--  /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
--  if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
--      || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
--    return X86_64_INTEGERSI_CLASS;
--  if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
--      || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
--    return X86_64_INTEGER_CLASS;
--
--  /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used.  */
--  if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
--      || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
--    return X86_64_MEMORY_CLASS;
--
--  /* Rule #6: Otherwise class SSE is used.  */
--  return X86_64_SSE_CLASS;
--}
--
--/* Classify the argument of type TYPE and mode MODE.
--   CLASSES will be filled by the register class used to pass each word
--   of the operand.  The number of words is returned.  In case the parameter
--   should be passed in memory, 0 is returned. As a special case for zero
--   sized containers, classes[0] will be NO_CLASS and 1 is returned.
--
--   BIT_OFFSET is used internally for handling records and specifies offset
--   of the offset in bits modulo 256 to avoid overflow cases.
--
--   See the x86-64 PS ABI for details.
--*/
--
--static int
--classify_argument (enum machine_mode mode, tree type,
--		   enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
--{
--  HOST_WIDE_INT bytes =
--    (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
--  int words = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
--
--  /* Variable sized entities are always passed/returned in memory.  */
--  if (bytes < 0)
--    return 0;
--
--  if (mode != VOIDmode
--      && MUST_PASS_IN_STACK (mode, type))
--    return 0;
--
--  if (type && AGGREGATE_TYPE_P (type))
--    {
--      int i;
--      tree field;
--      enum x86_64_reg_class subclasses[MAX_CLASSES];
--
--      /* On x86-64 we pass structures larger than 16 bytes on the stack.  */
--      if (bytes > 16)
--	return 0;
--
--      for (i = 0; i < words; i++)
--	classes[i] = X86_64_NO_CLASS;
--
--      /* Zero sized arrays or structures are NO_CLASS.  We return 0 to
--	 signalize memory class, so handle it as special case.  */
--      if (!words)
--	{
--	  classes[0] = X86_64_NO_CLASS;
--	  return 1;
--	}
--
--      /* Classify each field of record and merge classes.  */
--      if (TREE_CODE (type) == RECORD_TYPE)
--	{
--	  /* For classes first merge in the field of the subclasses.  */
--	  if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
--	    {
--	      tree bases = TYPE_BINFO_BASETYPES (type);
--	      int n_bases = TREE_VEC_LENGTH (bases);
--	      int i;
--
--	      for (i = 0; i < n_bases; ++i)
--		{
--		   tree binfo = TREE_VEC_ELT (bases, i);
--		   int num;
--		   int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
--		   tree type = BINFO_TYPE (binfo);
--
--		   num = classify_argument (TYPE_MODE (type),
--					    type, subclasses,
--					    (offset + bit_offset) % 256);
--		   if (!num)
--		     return 0;
--		   for (i = 0; i < num; i++)
--		     {
--		       int pos = (offset + (bit_offset % 64)) / 8 / 8;
--		       classes[i + pos] =
--			 merge_classes (subclasses[i], classes[i + pos]);
--		     }
--		}
--	    }
--	  /* And now merge the fields of structure.  */
--	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
--	    {
--	      if (TREE_CODE (field) == FIELD_DECL)
--		{
--		  int num;
--
--		  /* Bitfields are always classified as integer.  Handle them
--		     early, since later code would consider them to be
--		     misaligned integers.  */
--		  if (DECL_BIT_FIELD (field))
--		    {
--		      for (i = int_bit_position (field) / 8 / 8;
--			   i < (int_bit_position (field)
--			        + tree_low_cst (DECL_SIZE (field), 0)
--				+ 63) / 8 / 8; i++)
--			classes[i] =
--			  merge_classes (X86_64_INTEGER_CLASS,
--					 classes[i]);
--		    }
--		  else
--		    {
--		      num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
--					       TREE_TYPE (field), subclasses,
--					       (int_bit_position (field)
--						+ bit_offset) % 256);
--		      if (!num)
--			return 0;
--		      for (i = 0; i < num; i++)
--			{
--			  int pos =
--			    (int_bit_position (field) + (bit_offset % 64)) / 8 / 8;
--			  classes[i + pos] =
--			    merge_classes (subclasses[i], classes[i + pos]);
--			}
--		    }
--		}
--	    }
--	}
--      /* Arrays are handled as small records.  */
--      else if (TREE_CODE (type) == ARRAY_TYPE)
--	{
--	  int num;
--	  num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
--				   TREE_TYPE (type), subclasses, bit_offset);
--	  if (!num)
--	    return 0;
--
--	  /* The partial classes are now full classes.  */
--	  if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
--	    subclasses[0] = X86_64_SSE_CLASS;
--	  if (subclasses[0] == X86_64_INTEGERSI_CLASS && bytes != 4)
--	    subclasses[0] = X86_64_INTEGER_CLASS;
--
--	  for (i = 0; i < words; i++)
--	    classes[i] = subclasses[i % num];
--	}
--      /* Unions are similar to RECORD_TYPE but offset is always 0.  */
--      else if (TREE_CODE (type) == UNION_TYPE
--	       || TREE_CODE (type) == QUAL_UNION_TYPE)
--	{
--	  /* For classes first merge in the field of the subclasses.  */
--	  if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
--	    {
--	      tree bases = TYPE_BINFO_BASETYPES (type);
--	      int n_bases = TREE_VEC_LENGTH (bases);
--	      int i;
--
--	      for (i = 0; i < n_bases; ++i)
--		{
--		   tree binfo = TREE_VEC_ELT (bases, i);
--		   int num;
--		   int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
--		   tree type = BINFO_TYPE (binfo);
--
--		   num = classify_argument (TYPE_MODE (type),
--					    type, subclasses,
--					    (offset + (bit_offset % 64)) % 256);
--		   if (!num)
--		     return 0;
--		   for (i = 0; i < num; i++)
--		     {
--		       int pos = (offset + (bit_offset % 64)) / 8 / 8;
--		       classes[i + pos] =
--			 merge_classes (subclasses[i], classes[i + pos]);
--		     }
--		}
--	    }
--	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
--	    {
--	      if (TREE_CODE (field) == FIELD_DECL)
--		{
--		  int num;
--		  num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
--					   TREE_TYPE (field), subclasses,
--					   bit_offset);
--		  if (!num)
--		    return 0;
--		  for (i = 0; i < num; i++)
--		    classes[i] = merge_classes (subclasses[i], classes[i]);
--		}
--	    }
--	}
--      else if (TREE_CODE (type) == SET_TYPE)
--	{
--	  if (bytes <= 4)
--	    {
--	      classes[0] = X86_64_INTEGERSI_CLASS;
--	      return 1;
--	    }
--	  else if (bytes <= 8)
--	    {
--	      classes[0] = X86_64_INTEGER_CLASS;
--	      return 1;
--	    }
--	  else if (bytes <= 12)
--	    {
--	      classes[0] = X86_64_INTEGER_CLASS;
--	      classes[1] = X86_64_INTEGERSI_CLASS;
--	      return 2;
--	    }
--	  else
--	    {
--	      classes[0] = X86_64_INTEGER_CLASS;
--	      classes[1] = X86_64_INTEGER_CLASS;
--	      return 2;
--	    }
--	}
--      else
--	abort ();
--
--      /* Final merger cleanup.  */
--      for (i = 0; i < words; i++)
--	{
--	  /* If one class is MEMORY, everything should be passed in
--	     memory.  */
--	  if (classes[i] == X86_64_MEMORY_CLASS)
--	    return 0;
--
--	  /* The X86_64_SSEUP_CLASS should be always preceded by
--	     X86_64_SSE_CLASS.  */
--	  if (classes[i] == X86_64_SSEUP_CLASS
--	      && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
--	    classes[i] = X86_64_SSE_CLASS;
--
--	  /*  X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS.  */
--	  if (classes[i] == X86_64_X87UP_CLASS
--	      && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
--	    classes[i] = X86_64_SSE_CLASS;
--	}
--      return words;
--    }
--
--  /* Compute alignment needed.  We align all types to natural boundaries with
--     exception of XFmode that is aligned to 64bits.  */
--  if (mode != VOIDmode && mode != BLKmode)
--    {
--      int mode_alignment = GET_MODE_BITSIZE (mode);
--
--      if (mode == XFmode)
--	mode_alignment = 128;
--      else if (mode == XCmode)
--	mode_alignment = 256;
--      if (COMPLEX_MODE_P (mode))
--	mode_alignment /= 2;
--      /* Misaligned fields are always returned in memory.  */
--      if (bit_offset % mode_alignment)
--	return 0;
--    }
--
--  /* Classification of atomic types.  */
--  switch (mode)
--    {
--    case DImode:
--    case SImode:
--    case HImode:
--    case QImode:
--    case CSImode:
--    case CHImode:
--    case CQImode:
--      if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
--	classes[0] = X86_64_INTEGERSI_CLASS;
--      else
--	classes[0] = X86_64_INTEGER_CLASS;
--      return 1;
--    case CDImode:
--    case TImode:
--      classes[0] = classes[1] = X86_64_INTEGER_CLASS;
--      return 2;
--    case CTImode:
--      classes[0] = classes[1] = X86_64_INTEGER_CLASS;
--      classes[2] = classes[3] = X86_64_INTEGER_CLASS;
--      return 4;
--    case SFmode:
--      if (!(bit_offset % 64))
--	classes[0] = X86_64_SSESF_CLASS;
--      else
--	classes[0] = X86_64_SSE_CLASS;
--      return 1;
--    case DFmode:
--      classes[0] = X86_64_SSEDF_CLASS;
--      return 1;
--    case XFmode:
--      classes[0] = X86_64_X87_CLASS;
--      classes[1] = X86_64_X87UP_CLASS;
--      return 2;
--    case TFmode:
--    case TCmode:
--      return 0;
--    case XCmode:
--      classes[0] = X86_64_X87_CLASS;
--      classes[1] = X86_64_X87UP_CLASS;
--      classes[2] = X86_64_X87_CLASS;
--      classes[3] = X86_64_X87UP_CLASS;
--      return 4;
--    case DCmode:
--      classes[0] = X86_64_SSEDF_CLASS;
--      classes[1] = X86_64_SSEDF_CLASS;
--      return 2;
--    case SCmode:
--      classes[0] = X86_64_SSE_CLASS;
--      return 1;
--    case V4SFmode:
--    case V4SImode:
--    case V16QImode:
--    case V8HImode:
--    case V2DFmode:
--    case V2DImode:
--      classes[0] = X86_64_SSE_CLASS;
--      classes[1] = X86_64_SSEUP_CLASS;
--      return 2;
--    case V2SFmode:
--    case V2SImode:
--    case V4HImode:
--    case V8QImode:
--      return 0;
--    case BLKmode:
--    case VOIDmode:
--      return 0;
--    default:
--      abort ();
--    }
--}
--
--/* Examine the argument and return set number of register required in each
--   class.  Return 0 iff parameter should be passed in memory.  */
--static int
--examine_argument (enum machine_mode mode, tree type, int in_return,
--		  int *int_nregs, int *sse_nregs)
--{
--  enum x86_64_reg_class class[MAX_CLASSES];
--  int n = classify_argument (mode, type, class, 0);
--
--  *int_nregs = 0;
--  *sse_nregs = 0;
--  if (!n)
--    return 0;
--  for (n--; n >= 0; n--)
--    switch (class[n])
--      {
--      case X86_64_INTEGER_CLASS:
--      case X86_64_INTEGERSI_CLASS:
--	(*int_nregs)++;
--	break;
--      case X86_64_SSE_CLASS:
--      case X86_64_SSESF_CLASS:
--      case X86_64_SSEDF_CLASS:
--	(*sse_nregs)++;
--	break;
--      case X86_64_NO_CLASS:
--      case X86_64_SSEUP_CLASS:
--	break;
--      case X86_64_X87_CLASS:
--      case X86_64_X87UP_CLASS:
--	if (!in_return)
--	  return 0;
--	break;
--      case X86_64_MEMORY_CLASS:
--	abort ();
--      }
--  return 1;
--}
--/* Construct container for the argument used by GCC interface.  See
--   FUNCTION_ARG for the detailed description.  */
--static rtx
--construct_container (enum machine_mode mode, tree type, int in_return,
--		     int nintregs, int nsseregs, const int * intreg,
--		     int sse_regno)
--{
--  enum machine_mode tmpmode;
--  int bytes =
--    (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
--  enum x86_64_reg_class class[MAX_CLASSES];
--  int n;
--  int i;
--  int nexps = 0;
--  int needed_sseregs, needed_intregs;
--  rtx exp[MAX_CLASSES];
--  rtx ret;
--
--  n = classify_argument (mode, type, class, 0);
--  if (TARGET_DEBUG_ARG)
--    {
--      if (!n)
--	fprintf (stderr, "Memory class\n");
--      else
--	{
--	  fprintf (stderr, "Classes:");
--	  for (i = 0; i < n; i++)
--	    {
--	      fprintf (stderr, " %s", x86_64_reg_class_name[class[i]]);
--	    }
--	   fprintf (stderr, "\n");
--	}
--    }
--  if (!n)
--    return NULL;
--  if (!examine_argument (mode, type, in_return, &needed_intregs, &needed_sseregs))
--    return NULL;
--  if (needed_intregs > nintregs || needed_sseregs > nsseregs)
--    return NULL;
--
--  /* First construct simple cases.  Avoid SCmode, since we want to use
--     single register to pass this type.  */
--  if (n == 1 && mode != SCmode)
--    switch (class[0])
--      {
--      case X86_64_INTEGER_CLASS:
--      case X86_64_INTEGERSI_CLASS:
--	return gen_rtx_REG (mode, intreg[0]);
--      case X86_64_SSE_CLASS:
--      case X86_64_SSESF_CLASS:
--      case X86_64_SSEDF_CLASS:
--	return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
--      case X86_64_X87_CLASS:
--	return gen_rtx_REG (mode, FIRST_STACK_REG);
--      case X86_64_NO_CLASS:
--	/* Zero sized array, struct or class.  */
--	return NULL;
--      default:
--	abort ();
--      }
--  if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] == X86_64_SSEUP_CLASS
--      && mode != BLKmode)
--    return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
--  if (n == 2
--      && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS)
--    return gen_rtx_REG (XFmode, FIRST_STACK_REG);
--  if (n == 2 && class[0] == X86_64_INTEGER_CLASS
--      && class[1] == X86_64_INTEGER_CLASS
--      && (mode == CDImode || mode == TImode || mode == TFmode)
--      && intreg[0] + 1 == intreg[1])
--    return gen_rtx_REG (mode, intreg[0]);
--  if (n == 4
--      && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS
--      && class[2] == X86_64_X87_CLASS && class[3] == X86_64_X87UP_CLASS
--      && mode != BLKmode)
--    return gen_rtx_REG (XCmode, FIRST_STACK_REG);
--
--  /* Otherwise figure out the entries of the PARALLEL.  */
--  for (i = 0; i < n; i++)
--    {
--      switch (class[i])
--        {
--	  case X86_64_NO_CLASS:
--	    break;
--	  case X86_64_INTEGER_CLASS:
--	  case X86_64_INTEGERSI_CLASS:
--	    /* Merge TImodes on aligned occasions here too.  */
--	    if (i * 8 + 8 > bytes)
--	      tmpmode = mode_for_size ((bytes - i * 8) * BITS_PER_UNIT, MODE_INT, 0);
--	    else if (class[i] == X86_64_INTEGERSI_CLASS)
--	      tmpmode = SImode;
--	    else
--	      tmpmode = DImode;
--	    /* We've requested 24 bytes we don't have mode for.  Use DImode.  */
--	    if (tmpmode == BLKmode)
--	      tmpmode = DImode;
--	    exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
--					       gen_rtx_REG (tmpmode, *intreg),
--					       GEN_INT (i*8));
--	    intreg++;
--	    break;
--	  case X86_64_SSESF_CLASS:
--	    exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
--					       gen_rtx_REG (SFmode,
--							    SSE_REGNO (sse_regno)),
--					       GEN_INT (i*8));
--	    sse_regno++;
--	    break;
--	  case X86_64_SSEDF_CLASS:
--	    exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
--					       gen_rtx_REG (DFmode,
--							    SSE_REGNO (sse_regno)),
--					       GEN_INT (i*8));
--	    sse_regno++;
--	    break;
--	  case X86_64_SSE_CLASS:
--	    if (i < n - 1 && class[i + 1] == X86_64_SSEUP_CLASS)
--	      tmpmode = TImode;
--	    else
--	      tmpmode = DImode;
--	    exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
--					       gen_rtx_REG (tmpmode,
--							    SSE_REGNO (sse_regno)),
--					       GEN_INT (i*8));
--	    if (tmpmode == TImode)
--	      i++;
--	    sse_regno++;
--	    break;
--	  default:
--	    abort ();
--	}
--    }
--  ret =  gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
--  for (i = 0; i < nexps; i++)
--    XVECEXP (ret, 0, i) = exp [i];
--  return ret;
--}
--
--/* Update the data in CUM to advance over an argument
--   of mode MODE and data type TYPE.
--   (TYPE is null for libcalls where that information may not be available.)  */
--
--void
--function_arg_advance (CUMULATIVE_ARGS *cum,	/* current arg information */
--		      enum machine_mode mode,	/* current arg mode */
--		      tree type,	/* type of the argument or 0 if lib support */
--		      int named)	/* whether or not the argument was named */
--{
--  int bytes =
--    (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
--  int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
--
--  if (TARGET_DEBUG_ARG)
--    fprintf (stderr,
--	     "function_adv (sz=%d, wds=%2d, nregs=%d, ssenregs=%d, mode=%s, named=%d)\n\n",
--	     words, cum->words, cum->nregs, cum->sse_nregs, GET_MODE_NAME (mode), named);
--  if (TARGET_64BIT)
--    {
--      int int_nregs, sse_nregs;
--      if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs))
--	cum->words += words;
--      else if (sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
--	{
--	  cum->nregs -= int_nregs;
--	  cum->sse_nregs -= sse_nregs;
--	  cum->regno += int_nregs;
--	  cum->sse_regno += sse_nregs;
--	}
--      else
--	cum->words += words;
--    }
--  else
--    {
--      if (TARGET_SSE && SSE_REG_MODE_P (mode)
--	  && (!type || !AGGREGATE_TYPE_P (type)))
--	{
--	  cum->sse_words += words;
--	  cum->sse_nregs -= 1;
--	  cum->sse_regno += 1;
--	  if (cum->sse_nregs <= 0)
--	    {
--	      cum->sse_nregs = 0;
--	      cum->sse_regno = 0;
--	    }
--	}
--      else if (TARGET_MMX && MMX_REG_MODE_P (mode)
--	       && (!type || !AGGREGATE_TYPE_P (type)))
--	{
--	  cum->mmx_words += words;
--	  cum->mmx_nregs -= 1;
--	  cum->mmx_regno += 1;
--	  if (cum->mmx_nregs <= 0)
--	    {
--	      cum->mmx_nregs = 0;
--	      cum->mmx_regno = 0;
--	    }
--	}
--      else
--	{
--	  cum->words += words;
--	  cum->nregs -= words;
--	  cum->regno += words;
--
--	  if (cum->nregs <= 0)
--	    {
--	      cum->nregs = 0;
--	      cum->regno = 0;
--	    }
--	}
--    }
--  return;
--}
--
--/* A subroutine of function_arg.  We want to pass a parameter whose nominal
--   type is MODE in REGNO.  We try to minimize ABI variation, so MODE may not
--   actually be valid for REGNO with the current ISA.  In this case, ALT_MODE
--   is used instead.  It must be the same size as MODE, and must be known to
--   be valid for REGNO.  Finally, ORIG_MODE is the original mode of the 
--   parameter, as seen by the type system.  This may be different from MODE
--   when we're mucking with things minimizing ABI variations.
--
--   Returns a REG or a PARALLEL as appropriate.  */
--
--static rtx
--gen_reg_or_parallel (enum machine_mode mode, enum machine_mode alt_mode,
--		     enum machine_mode orig_mode, unsigned int regno)
--{
--  rtx tmp;
--
--  if (HARD_REGNO_MODE_OK (regno, mode))
--    tmp = gen_rtx_REG (mode, regno);
--  else
--    {
--      tmp = gen_rtx_REG (alt_mode, regno);
--      tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
--      tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
--    }
--
--  return tmp;
--}
--
--/* Define where to put the arguments to a function.
--   Value is zero to push the argument on the stack,
--   or a hard register in which to store the argument.
--
--   MODE is the argument's machine mode.
--   TYPE is the data type of the argument (as a tree).
--    This is null for libcalls where that information may
--    not be available.
--   CUM is a variable of type CUMULATIVE_ARGS which gives info about
--    the preceding args and about the function being called.
--   NAMED is nonzero if this argument is a named parameter
--    (otherwise it is an extra parameter matching an ellipsis).  */
--
--rtx
--function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
--	      tree type, int named)
--{
--  enum machine_mode mode = orig_mode;
--  rtx ret = NULL_RTX;
--  int bytes =
--    (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
--  int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
--  static bool warnedsse, warnedmmx;
--
--  /* Handle a hidden AL argument containing number of registers for varargs
--     x86-64 functions.  For i386 ABI just return constm1_rtx to avoid
--     any AL settings.  */
--  if (mode == VOIDmode)
--    {
--      if (TARGET_64BIT)
--	return GEN_INT (cum->maybe_vaarg
--			? (cum->sse_nregs < 0
--			   ? SSE_REGPARM_MAX
--			   : cum->sse_regno)
--			: -1);
--      else
--	return constm1_rtx;
--    }
--  if (TARGET_64BIT)
--    ret = construct_container (mode, type, 0, cum->nregs, cum->sse_nregs,
--			       &x86_64_int_parameter_registers [cum->regno],
--			       cum->sse_regno);
--  else
--    switch (mode)
--      {
--	/* For now, pass fp/complex values on the stack.  */
--      default:
--	break;
--
--      case BLKmode:
--	if (bytes < 0)
--	  break;
--	/* FALLTHRU */
--      case DImode:
--      case SImode:
--      case HImode:
--      case QImode:
--	if (words <= cum->nregs)
--	  {
--	    int regno = cum->regno;
--
--	    /* Fastcall allocates the first two DWORD (SImode) or
--	       smaller arguments to ECX and EDX.  */
--	    if (cum->fastcall)
--	      {
--	        if (mode == BLKmode || mode == DImode)
--	          break;
--
--	        /* ECX not EAX is the first allocated register.  */
--	        if (regno == 0)
--		  regno = 2;
--	      }
--	    ret = gen_rtx_REG (mode, regno);
--	  }
--	break;
--      case TImode:
--      case V16QImode:
--      case V8HImode:
--      case V4SImode:
--      case V2DImode:
--      case V4SFmode:
--      case V2DFmode:
--	if (!type || !AGGREGATE_TYPE_P (type))
--	  {
--	    if (!TARGET_SSE && !warnedmmx && cum->warn_sse)
--	      {
--		warnedsse = true;
--		warning ("SSE vector argument without SSE enabled "
--			 "changes the ABI");
--	      }
--	    if (cum->sse_nregs)
--	      ret = gen_reg_or_parallel (mode, TImode, orig_mode,
--					 cum->sse_regno + FIRST_SSE_REG);
--	  }
--	break;
--      case V8QImode:
--      case V4HImode:
--      case V2SImode:
--      case V2SFmode:
--	if (!type || !AGGREGATE_TYPE_P (type))
--	  {
--	    if (!TARGET_MMX && !warnedmmx && cum->warn_mmx)
--	      {
--		warnedmmx = true;
--		warning ("MMX vector argument without MMX enabled "
--			 "changes the ABI");
--	      }
--	    if (cum->mmx_nregs)
--	      ret = gen_reg_or_parallel (mode, DImode, orig_mode,
--					 cum->mmx_regno + FIRST_MMX_REG);
--	  }
--	break;
--      }
--
--  if (TARGET_DEBUG_ARG)
--    {
--      fprintf (stderr,
--	       "function_arg (size=%d, wds=%2d, nregs=%d, mode=%4s, named=%d, ",
--	       words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
--
--      if (ret)
--	print_simple_rtl (stderr, ret);
--      else
--	fprintf (stderr, ", stack");
--
--      fprintf (stderr, " )\n");
--    }
--
--  return ret;
--}
--
--/* A C expression that indicates when an argument must be passed by
--   reference.  If nonzero for an argument, a copy of that argument is
--   made in memory and a pointer to the argument is passed instead of
--   the argument itself.  The pointer is passed in whatever way is
--   appropriate for passing a pointer to that type.  */
--
--int
--function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
--				enum machine_mode mode ATTRIBUTE_UNUSED,
--				tree type, int named ATTRIBUTE_UNUSED)
--{
--  if (!TARGET_64BIT)
--    return 0;
--
--  if (type && int_size_in_bytes (type) == -1)
--    {
--      if (TARGET_DEBUG_ARG)
--	fprintf (stderr, "function_arg_pass_by_reference\n");
--      return 1;
--    }
--
--  return 0;
--}
--
--/* Return true when TYPE should be 128bit aligned for 32bit argument passing
--   ABI  */
--static bool
--contains_128bit_aligned_vector_p (tree type)
--{
--  enum machine_mode mode = TYPE_MODE (type);
--  if (SSE_REG_MODE_P (mode)
--      && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
--    return true;
--  if (TYPE_ALIGN (type) < 128)
--    return false;
--
--  if (AGGREGATE_TYPE_P (type))
--    {
--      /* Walk the aggregates recursively.  */
--      if (TREE_CODE (type) == RECORD_TYPE
--	  || TREE_CODE (type) == UNION_TYPE
--	  || TREE_CODE (type) == QUAL_UNION_TYPE)
--	{
--	  tree field;
--
--	  if (TYPE_BINFO (type) != NULL
--	      && TYPE_BINFO_BASETYPES (type) != NULL)
--	    {
--	      tree bases = TYPE_BINFO_BASETYPES (type);
--	      int n_bases = TREE_VEC_LENGTH (bases);
--	      int i;
--
--	      for (i = 0; i < n_bases; ++i)
--		{
--		  tree binfo = TREE_VEC_ELT (bases, i);
--		  tree type = BINFO_TYPE (binfo);
--
--		  if (contains_128bit_aligned_vector_p (type))
--		    return true;
--		}
--	    }
--	  /* And now merge the fields of structure.  */
--	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
--	    {
--	      if (TREE_CODE (field) == FIELD_DECL
--		  && contains_128bit_aligned_vector_p (TREE_TYPE (field)))
--		return true;
--	    }
--	}
--      /* Just for use if some languages passes arrays by value.  */
--      else if (TREE_CODE (type) == ARRAY_TYPE)
--	{
--	  if (contains_128bit_aligned_vector_p (TREE_TYPE (type)))
--	    return true;
--	}
--      else
--	abort ();
--    }
--  return false;
--}
--
--/* Gives the alignment boundary, in bits, of an argument with the
--   specified mode and type.  */
--
--int
--ix86_function_arg_boundary (enum machine_mode mode, tree type)
--{
--  int align;
--  if (type)
--    align = TYPE_ALIGN (type);
--  else
--    align = GET_MODE_ALIGNMENT (mode);
--  if (align < PARM_BOUNDARY)
--    align = PARM_BOUNDARY;
--  if (!TARGET_64BIT)
--    {
--      /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
--	 make an exception for SSE modes since these require 128bit
--	 alignment.
--
--	 The handling here differs from field_alignment.  ICC aligns MMX
--	 arguments to 4 byte boundaries, while structure fields are aligned
--	 to 8 byte boundaries.  */
--      if (!type)
--	{
--	  if (!SSE_REG_MODE_P (mode))
--	    align = PARM_BOUNDARY;
--	}
--      else
--	{
--	  if (!contains_128bit_aligned_vector_p (type))
--	    align = PARM_BOUNDARY;
--	}
--    }
--  if (align > 128)
--    align = 128;
--  return align;
--}
--
--/* Return true if N is a possible register number of function value.  */
--bool
--ix86_function_value_regno_p (int regno)
--{
--  if (!TARGET_64BIT)
--    {
--      return ((regno) == 0
--	      || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)
--	      || ((regno) == FIRST_SSE_REG && TARGET_SSE));
--    }
--  return ((regno) == 0 || (regno) == FIRST_FLOAT_REG
--	  || ((regno) == FIRST_SSE_REG && TARGET_SSE)
--	  || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387));
--}
--
--/* Define how to find the value returned by a function.
--   VALTYPE is the data type of the value (as a tree).
--   If the precise function being called is known, FUNC is its FUNCTION_DECL;
--   otherwise, FUNC is 0.  */
--rtx
--ix86_function_value (tree valtype)
--{
--  if (TARGET_64BIT)
--    {
--      rtx ret = construct_container (TYPE_MODE (valtype), valtype, 1,
--				     REGPARM_MAX, SSE_REGPARM_MAX,
--				     x86_64_int_return_registers, 0);
--      /* For zero sized structures, construct_container return NULL, but we need
--         to keep rest of compiler happy by returning meaningful value.  */
--      if (!ret)
--	ret = gen_rtx_REG (TYPE_MODE (valtype), 0);
--      return ret;
--    }
--  else
--    return gen_rtx_REG (TYPE_MODE (valtype),
--			ix86_value_regno (TYPE_MODE (valtype)));
--}
--
--/* Return false iff type is returned in memory.  */
--int
--ix86_return_in_memory (tree type)
--{
--  int needed_intregs, needed_sseregs, size;
--  enum machine_mode mode = TYPE_MODE (type);
--
--  if (TARGET_64BIT)
--    return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs);
--
--  if (mode == BLKmode)
--    return 1;
--
--  size = int_size_in_bytes (type);
--
--  if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
--    return 0;
--
--  if (VECTOR_MODE_P (mode) || mode == TImode)
--    {
--      /* User-created vectors small enough to fit in EAX.  */
--      if (size < 8)
--	return 0;
--
--      /* MMX/3dNow values are returned on the stack, since we've
--	 got to EMMS/FEMMS before returning.  */
--      if (size == 8)
--	return 1;
--
--      /* SSE values are returned in XMM0.  */
--      /* ??? Except when it doesn't exist?  We have a choice of
--	 either (1) being abi incompatible with a -march switch,
--	 or (2) generating an error here.  Given no good solution,
--	 I think the safest thing is one warning.  The user won't
--	 be able to use -Werror, but....  */
--      if (size == 16)
--	{
--	  static bool warned;
--
--	  if (TARGET_SSE)
--	    return 0;
--
--	  if (!warned)
--	    {
--	      warned = true;
--	      warning ("SSE vector return without SSE enabled "
--		       "changes the ABI");
--	    }
--	  return 1;
--	}
--    }
--
--  if (mode == XFmode)
--    return 0;
--
--  if (size > 12)
--    return 1;
--  return 0;
--}
--
--/* Define how to find the value returned by a library function
--   assuming the value has mode MODE.  */
--rtx
--ix86_libcall_value (enum machine_mode mode)
--{
--  if (TARGET_64BIT)
--    {
--      switch (mode)
--	{
--	case SFmode:
--	case SCmode:
--	case DFmode:
--	case DCmode:
--	  return gen_rtx_REG (mode, FIRST_SSE_REG);
--	case XFmode:
--	case XCmode:
--	  return gen_rtx_REG (mode, FIRST_FLOAT_REG);
--	case TFmode:
--	case TCmode:
--	  return NULL;
--	default:
--	  return gen_rtx_REG (mode, 0);
--	}
--    }
--  else
--    return gen_rtx_REG (mode, ix86_value_regno (mode));
--}
--
--/* Given a mode, return the register to use for a return value.  */
--
--static int
--ix86_value_regno (enum machine_mode mode)
--{
--  /* Floating point return values in %st(0).  */
--  if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_FLOAT_RETURNS_IN_80387)
--    return FIRST_FLOAT_REG;
--  /* 16-byte vector modes in %xmm0.  See ix86_return_in_memory for where
--     we prevent this case when sse is not available.  */
--  if (mode == TImode || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
--    return FIRST_SSE_REG;
--  /* Everything else in %eax.  */
--  return 0;
--}
--
--/* Create the va_list data type.  */
--
--static tree
--ix86_build_builtin_va_list (void)
--{
--  tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
--
--  /* For i386 we use plain pointer to argument area.  */
--  if (!TARGET_64BIT)
--    return build_pointer_type (char_type_node);
--
--  record = (*lang_hooks.types.make_type) (RECORD_TYPE);
--  type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
--
--  f_gpr = build_decl (FIELD_DECL, get_identifier ("gp_offset"),
--		      unsigned_type_node);
--  f_fpr = build_decl (FIELD_DECL, get_identifier ("fp_offset"),
--		      unsigned_type_node);
--  f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
--		      ptr_type_node);
--  f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
--		      ptr_type_node);
--
--  DECL_FIELD_CONTEXT (f_gpr) = record;
--  DECL_FIELD_CONTEXT (f_fpr) = record;
--  DECL_FIELD_CONTEXT (f_ovf) = record;
--  DECL_FIELD_CONTEXT (f_sav) = record;
--
--  TREE_CHAIN (record) = type_decl;
--  TYPE_NAME (record) = type_decl;
--  TYPE_FIELDS (record) = f_gpr;
--  TREE_CHAIN (f_gpr) = f_fpr;
--  TREE_CHAIN (f_fpr) = f_ovf;
--  TREE_CHAIN (f_ovf) = f_sav;
--
--  layout_type (record);
--
--  /* The correct type is an array type of one element.  */
--  return build_array_type (record, build_index_type (size_zero_node));
--}
--
--/* Perform any needed actions needed for a function that is receiving a
--   variable number of arguments.
--
--   CUM is as above.
--
--   MODE and TYPE are the mode and type of the current parameter.
--
--   PRETEND_SIZE is a variable that should be set to the amount of stack
--   that must be pushed by the prolog to pretend that our caller pushed
--   it.
--
--   Normally, this macro will push all remaining incoming registers on the
--   stack and set PRETEND_SIZE to the length of the registers pushed.  */
--
--void
--ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
--			     tree type, int *pretend_size ATTRIBUTE_UNUSED,
--			     int no_rtl)
--{
--  CUMULATIVE_ARGS next_cum;
--  rtx save_area = NULL_RTX, mem;
--  rtx label;
--  rtx label_ref;
--  rtx tmp_reg;
--  rtx nsse_reg;
--  int set;
--  tree fntype;
--  int stdarg_p;
--  int i;
--
--  if (!TARGET_64BIT)
--    return;
--
--  /* Indicate to allocate space on the stack for varargs save area.  */
--  ix86_save_varrargs_registers = 1;
--
--  cfun->stack_alignment_needed = 128;
--
--  fntype = TREE_TYPE (current_function_decl);
--  stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
--	      && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
--		  != void_type_node));
--
--  /* For varargs, we do not want to skip the dummy va_dcl argument.
--     For stdargs, we do want to skip the last named argument.  */
--  next_cum = *cum;
--  if (stdarg_p)
--    function_arg_advance (&next_cum, mode, type, 1);
--
--  if (!no_rtl)
--    save_area = frame_pointer_rtx;
--
--  set = get_varargs_alias_set ();
--
--  for (i = next_cum.regno; i < ix86_regparm; i++)
--    {
--      mem = gen_rtx_MEM (Pmode,
--			 plus_constant (save_area, i * UNITS_PER_WORD));
--      set_mem_alias_set (mem, set);
--      emit_move_insn (mem, gen_rtx_REG (Pmode,
--					x86_64_int_parameter_registers[i]));
--    }
--
--  if (next_cum.sse_nregs)
--    {
--      /* Now emit code to save SSE registers.  The AX parameter contains number
--	 of SSE parameter registers used to call this function.  We use
--	 sse_prologue_save insn template that produces computed jump across
--	 SSE saves.  We need some preparation work to get this working.  */
--
--      label = gen_label_rtx ();
--      label_ref = gen_rtx_LABEL_REF (Pmode, label);
--
--      /* Compute address to jump to :
--         label - 5*eax + nnamed_sse_arguments*5  */
--      tmp_reg = gen_reg_rtx (Pmode);
--      nsse_reg = gen_reg_rtx (Pmode);
--      emit_insn (gen_zero_extendqidi2 (nsse_reg, gen_rtx_REG (QImode, 0)));
--      emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
--			      gen_rtx_MULT (Pmode, nsse_reg,
--					    GEN_INT (4))));
--      if (next_cum.sse_regno)
--	emit_move_insn
--	  (nsse_reg,
--	   gen_rtx_CONST (DImode,
--			  gen_rtx_PLUS (DImode,
--					label_ref,
--					GEN_INT (next_cum.sse_regno * 4))));
--      else
--	emit_move_insn (nsse_reg, label_ref);
--      emit_insn (gen_subdi3 (nsse_reg, nsse_reg, tmp_reg));
--
--      /* Compute address of memory block we save into.  We always use pointer
--	 pointing 127 bytes after first byte to store - this is needed to keep
--	 instruction size limited by 4 bytes.  */
--      tmp_reg = gen_reg_rtx (Pmode);
--      emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
--			      plus_constant (save_area,
--					     8 * REGPARM_MAX + 127)));
--      mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
--      set_mem_alias_set (mem, set);
--      set_mem_align (mem, BITS_PER_WORD);
--
--      /* And finally do the dirty job!  */
--      emit_insn (gen_sse_prologue_save (mem, nsse_reg,
--					GEN_INT (next_cum.sse_regno), label));
--    }
--
--}
--
--/* Implement va_start.  */
--
--void
--ix86_va_start (tree valist, rtx nextarg)
--{
--  HOST_WIDE_INT words, n_gpr, n_fpr;
--  tree f_gpr, f_fpr, f_ovf, f_sav;
--  tree gpr, fpr, ovf, sav, t;
--
--  /* Only 64bit target needs something special.  */
--  if (!TARGET_64BIT)
--    {
--      std_expand_builtin_va_start (valist, nextarg);
--      return;
--    }
--
--  f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
--  f_fpr = TREE_CHAIN (f_gpr);
--  f_ovf = TREE_CHAIN (f_fpr);
--  f_sav = TREE_CHAIN (f_ovf);
--
--  valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
--  gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
--  fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
--  ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
--  sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
--
--  /* Count number of gp and fp argument registers used.  */
--  words = current_function_args_info.words;
--  n_gpr = current_function_args_info.regno;
--  n_fpr = current_function_args_info.sse_regno;
--
--  if (TARGET_DEBUG_ARG)
--    fprintf (stderr, "va_start: words = %d, n_gpr = %d, n_fpr = %d\n",
--	     (int) words, (int) n_gpr, (int) n_fpr);
--
--  t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
--	     build_int_2 (n_gpr * 8, 0));
--  TREE_SIDE_EFFECTS (t) = 1;
--  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
--
--  t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
--	     build_int_2 (n_fpr * 16 + 8*REGPARM_MAX, 0));
--  TREE_SIDE_EFFECTS (t) = 1;
--  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
--
--  /* Find the overflow area.  */
--  t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
--  if (words != 0)
--    t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
--	       build_int_2 (words * UNITS_PER_WORD, 0));
--  t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
--  TREE_SIDE_EFFECTS (t) = 1;
--  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
--
--  /* Find the register save area.
--     Prologue of the function save it right above stack frame.  */
--  t = make_tree (TREE_TYPE (sav), frame_pointer_rtx);
--  t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
--  TREE_SIDE_EFFECTS (t) = 1;
--  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
--}
--
--/* Implement va_arg.  */
--rtx
--ix86_va_arg (tree valist, tree type)
--{
--  static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
--  tree f_gpr, f_fpr, f_ovf, f_sav;
--  tree gpr, fpr, ovf, sav, t;
--  int size, rsize;
--  rtx lab_false, lab_over = NULL_RTX;
--  rtx addr_rtx, r;
--  rtx container;
--  int indirect_p = 0;
--
--  /* Only 64bit target needs something special.  */
--  if (!TARGET_64BIT)
--    {
--      return std_expand_builtin_va_arg (valist, type);
--    }
--
--  f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
--  f_fpr = TREE_CHAIN (f_gpr);
--  f_ovf = TREE_CHAIN (f_fpr);
--  f_sav = TREE_CHAIN (f_ovf);
--
--  valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
--  gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
--  fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
--  ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
--  sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
--
--  size = int_size_in_bytes (type);
--  if (size == -1)
--    {
--      /* Passed by reference.  */
--      indirect_p = 1;
--      type = build_pointer_type (type);
--      size = int_size_in_bytes (type);
--    }
--  rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
--
--  container = construct_container (TYPE_MODE (type), type, 0,
--				   REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
--  /*
--   * Pull the value out of the saved registers ...
--   */
--
--  addr_rtx = gen_reg_rtx (Pmode);
--
--  if (container)
--    {
--      rtx int_addr_rtx, sse_addr_rtx;
--      int needed_intregs, needed_sseregs;
--      int need_temp;
--
--      lab_over = gen_label_rtx ();
--      lab_false = gen_label_rtx ();
--
--      examine_argument (TYPE_MODE (type), type, 0,
--		        &needed_intregs, &needed_sseregs);
--
--
--      need_temp = ((needed_intregs && TYPE_ALIGN (type) > 64)
--		   || TYPE_ALIGN (type) > 128);
--
--      /* In case we are passing structure, verify that it is consecutive block
--         on the register save area.  If not we need to do moves.  */
--      if (!need_temp && !REG_P (container))
--	{
--	  /* Verify that all registers are strictly consecutive  */
--	  if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
--	    {
--	      int i;
--
--	      for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
--		{
--		  rtx slot = XVECEXP (container, 0, i);
--		  if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
--		      || INTVAL (XEXP (slot, 1)) != i * 16)
--		    need_temp = 1;
--		}
--	    }
--	  else
--	    {
--	      int i;
--
--	      for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
--		{
--		  rtx slot = XVECEXP (container, 0, i);
--		  if (REGNO (XEXP (slot, 0)) != (unsigned int) i
--		      || INTVAL (XEXP (slot, 1)) != i * 8)
--		    need_temp = 1;
--		}
--	    }
--	}
--      if (!need_temp)
--	{
--	  int_addr_rtx = addr_rtx;
--	  sse_addr_rtx = addr_rtx;
--	}
--      else
--	{
--	  int_addr_rtx = gen_reg_rtx (Pmode);
--	  sse_addr_rtx = gen_reg_rtx (Pmode);
--	}
--      /* First ensure that we fit completely in registers.  */
--      if (needed_intregs)
--	{
--	  emit_cmp_and_jump_insns (expand_expr
--				   (gpr, NULL_RTX, SImode, EXPAND_NORMAL),
--				   GEN_INT ((REGPARM_MAX - needed_intregs +
--					     1) * 8), GE, const1_rtx, SImode,
--				   1, lab_false);
--	}
--      if (needed_sseregs)
--	{
--	  emit_cmp_and_jump_insns (expand_expr
--				   (fpr, NULL_RTX, SImode, EXPAND_NORMAL),
--				   GEN_INT ((SSE_REGPARM_MAX -
--					     needed_sseregs + 1) * 16 +
--					    REGPARM_MAX * 8), GE, const1_rtx,
--				   SImode, 1, lab_false);
--	}
--
--      /* Compute index to start of area used for integer regs.  */
--      if (needed_intregs)
--	{
--	  t = build (PLUS_EXPR, ptr_type_node, sav, gpr);
--	  r = expand_expr (t, int_addr_rtx, Pmode, EXPAND_NORMAL);
--	  if (r != int_addr_rtx)
--	    emit_move_insn (int_addr_rtx, r);
--	}
--      if (needed_sseregs)
--	{
--	  t = build (PLUS_EXPR, ptr_type_node, sav, fpr);
--	  r = expand_expr (t, sse_addr_rtx, Pmode, EXPAND_NORMAL);
--	  if (r != sse_addr_rtx)
--	    emit_move_insn (sse_addr_rtx, r);
--	}
--      if (need_temp)
--	{
--	  int i;
--	  rtx mem;
--	  rtx x;
--
--	  /* Never use the memory itself, as it has the alias set.  */
--	  x = XEXP (assign_temp (type, 0, 1, 0), 0);
--	  mem = gen_rtx_MEM (BLKmode, x);
--	  force_operand (x, addr_rtx);
--	  set_mem_alias_set (mem, get_varargs_alias_set ());
--	  set_mem_align (mem, BITS_PER_UNIT);
--
--	  for (i = 0; i < XVECLEN (container, 0); i++)
--	    {
--	      rtx slot = XVECEXP (container, 0, i);
--	      rtx reg = XEXP (slot, 0);
--	      enum machine_mode mode = GET_MODE (reg);
--	      rtx src_addr;
--	      rtx src_mem;
--	      int src_offset;
--	      rtx dest_mem;
--
--	      if (SSE_REGNO_P (REGNO (reg)))
--		{
--		  src_addr = sse_addr_rtx;
--		  src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
--		}
--	      else
--		{
--		  src_addr = int_addr_rtx;
--		  src_offset = REGNO (reg) * 8;
--		}
--	      src_mem = gen_rtx_MEM (mode, src_addr);
--	      set_mem_alias_set (src_mem, get_varargs_alias_set ());
--	      src_mem = adjust_address (src_mem, mode, src_offset);
--	      dest_mem = adjust_address (mem, mode, INTVAL (XEXP (slot, 1)));
--	      emit_move_insn (dest_mem, src_mem);
--	    }
--	}
--
--      if (needed_intregs)
--	{
--	  t =
--	    build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
--		   build_int_2 (needed_intregs * 8, 0));
--	  t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
--	  TREE_SIDE_EFFECTS (t) = 1;
--	  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
--	}
--      if (needed_sseregs)
--	{
--	  t =
--	    build (PLUS_EXPR, TREE_TYPE (fpr), fpr,
--		   build_int_2 (needed_sseregs * 16, 0));
--	  t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, t);
--	  TREE_SIDE_EFFECTS (t) = 1;
--	  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
--	}
--
--      emit_jump_insn (gen_jump (lab_over));
--      emit_barrier ();
--      emit_label (lab_false);
--    }
--
--  /* ... otherwise out of the overflow area.  */
--
--  /* Care for on-stack alignment if needed.  */
--  if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64)
--    t = ovf;
--  else
--    {
--      HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8;
--      t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align - 1, 0));
--      t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
--    }
--  t = save_expr (t);
--
--  r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
--  if (r != addr_rtx)
--    emit_move_insn (addr_rtx, r);
--
--  t =
--    build (PLUS_EXPR, TREE_TYPE (t), t,
--	   build_int_2 (rsize * UNITS_PER_WORD, 0));
--  t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
--  TREE_SIDE_EFFECTS (t) = 1;
--  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
--
--  if (container)
--    emit_label (lab_over);
--
--  if (indirect_p)
--    {
--      r = gen_rtx_MEM (Pmode, addr_rtx);
--      set_mem_alias_set (r, get_varargs_alias_set ());
--      emit_move_insn (addr_rtx, r);
--    }
--
--  return addr_rtx;
--}
--
--/* Return nonzero if OP is either a i387 or SSE fp register.  */
--int
--any_fp_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
--{
--  return ANY_FP_REG_P (op);
--}
--
--/* Return nonzero if OP is an i387 fp register.  */
--int
--fp_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
--{
--  return FP_REG_P (op);
--}
--
--/* Return nonzero if OP is a non-fp register_operand.  */
--int
--register_and_not_any_fp_reg_operand (rtx op, enum machine_mode mode)
--{
--  return register_operand (op, mode) && !ANY_FP_REG_P (op);
--}
--
--/* Return nonzero if OP is a register operand other than an
--   i387 fp register.  */
--int
--register_and_not_fp_reg_operand (rtx op, enum machine_mode mode)
--{
--  return register_operand (op, mode) && !FP_REG_P (op);
--}
--
--/* Return nonzero if OP is general operand representable on x86_64.  */
--
--int
--x86_64_general_operand (rtx op, enum machine_mode mode)
--{
--  if (!TARGET_64BIT)
--    return general_operand (op, mode);
--  if (nonimmediate_operand (op, mode))
--    return 1;
--  return x86_64_sign_extended_value (op);
--}
--
--/* Return nonzero if OP is general operand representable on x86_64
--   as either sign extended or zero extended constant.  */
--
--int
--x86_64_szext_general_operand (rtx op, enum machine_mode mode)
--{
--  if (!TARGET_64BIT)
--    return general_operand (op, mode);
--  if (nonimmediate_operand (op, mode))
--    return 1;
--  return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
--}
--
--/* Return nonzero if OP is nonmemory operand representable on x86_64.  */
--
--int
--x86_64_nonmemory_operand (rtx op, enum machine_mode mode)
--{
--  if (!TARGET_64BIT)
--    return nonmemory_operand (op, mode);
--  if (register_operand (op, mode))
--    return 1;
--  return x86_64_sign_extended_value (op);
--}
--
--/* Return nonzero if OP is nonmemory operand acceptable by movabs patterns.  */
--
--int
--x86_64_movabs_operand (rtx op, enum machine_mode mode)
--{
--  if (!TARGET_64BIT || !flag_pic)
--    return nonmemory_operand (op, mode);
--  if (register_operand (op, mode) || x86_64_sign_extended_value (op))