OSDN Git Service

See the ChangeLog on the branch for more details.
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Mar 2000 03:16:41 +0000 (03:16 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Mar 2000 03:16:41 +0000 (03:16 +0000)
* configure.in: Merge in changes from newppc-branch.
* configure: Regenerate.
* config/rs6000/*: Merge in changes from newppc-branch.
Also correct copyright notices.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32575 138bc75d-0d04-0410-961f-82ee72b054a4

37 files changed:
gcc/ChangeLog
gcc/config/rs6000/aix.h [new file with mode: 0644]
gcc/config/rs6000/aix31.h
gcc/config/rs6000/aix3newas.h
gcc/config/rs6000/aix41.h
gcc/config/rs6000/aix43.h
gcc/config/rs6000/beos.h
gcc/config/rs6000/cygwin.h [deleted file]
gcc/config/rs6000/eabi-ci.asm
gcc/config/rs6000/eabi-cn.asm
gcc/config/rs6000/eabi-ctors.c
gcc/config/rs6000/eabi.h
gcc/config/rs6000/lynx.h
gcc/config/rs6000/netware.h
gcc/config/rs6000/nt-ci.asm [deleted file]
gcc/config/rs6000/nt-cn.asm [deleted file]
gcc/config/rs6000/ntstack.asm [deleted file]
gcc/config/rs6000/rs6000-protos.h [new file with mode: 0644]
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/sol2.h
gcc/config/rs6000/sysv4.h
gcc/config/rs6000/sysv4le.h
gcc/config/rs6000/t-aix43
gcc/config/rs6000/t-ppccomm
gcc/config/rs6000/t-ppcgas
gcc/config/rs6000/t-winnt [deleted file]
gcc/config/rs6000/tramp.asm
gcc/config/rs6000/vxppc.h
gcc/config/rs6000/vxppcle.h [new file with mode: 0644]
gcc/config/rs6000/win-nt.h [deleted file]
gcc/config/rs6000/x-aix41
gcc/config/rs6000/x-aix41-gld [deleted file]
gcc/config/rs6000/x-aix43 [deleted file]
gcc/configure
gcc/configure.in

index c16f4b6..5b521c3 100644 (file)
@@ -1,3 +1,12 @@
+2000-03-15  Geoff Keating  <geoffk@cygnus.com>
+
+       See the ChangeLog on the branch for more details.
+       
+       * configure.in: Merge in changes from newppc-branch.
+       * configure: Regenerate.
+       * config/rs6000/*: Merge in changes from newppc-branch.
+       Also correct copyright notices.
+
 Wed Mar 15 15:43:38 2000  Jeffrey A Law  (law@cygnus.com)
 
        * acconfig.h (HAVE_GAS_WEAK): New define.
diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
new file mode 100644 (file)
index 0000000..9f2b996
--- /dev/null
@@ -0,0 +1,544 @@
+/* Definitions of target machine for GNU compiler,
+   for IBM RS/6000 POWER running AIX.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Yes!  We are AIX!  */
+#define DEFAULT_ABI ABI_AIX
+#define TARGET_OBJECT_FORMAT OBJECT_XCOFF
+
+/* The RS/6000 uses the XCOFF format.  */
+
+#define XCOFF_DEBUGGING_INFO
+
+/* Define if the object format being used is COFF or a superset.  */
+#define OBJECT_FORMAT_COFF
+
+/* Define the magic numbers that we recognize as COFF.
+    AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects, but collect2.c
+    does not include files in the correct order to conditionally define
+    the symbolic name in this macro.
+    The AIX linker accepts import/export files as object files,
+    so accept "#!" (0x2321) magic number.  */
+#define MY_ISCOFF(magic) \
+  ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \
+   || (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0x2321)
+
+/* This is the only version of nm that collect2 can work with.  */
+#define REAL_NM_FILE_NAME "/usr/ucb/nm"
+
+/* We don't have GAS for the RS/6000 yet, so don't write out special
+    .stabs in cc1plus.  */
+
+#define FASCIST_ASSEMBLER
+
+/* AIX does not have any init/fini or ctor/dtor sections, so create
+    static constructors and destructors as normal functions.  */
+/* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */
+/* #define ASM_OUTPUT_DESTRUCTOR(file, name) */
+
+/* The prefix to add to user-visible assembler symbols. */
+#define USER_LABEL_PREFIX "."
+
+/* Don't turn -B into -L if the argument specifies a relative file name.  */
+#define RELATIVE_PREFIX_NOT_LINKDIR
+
+/* Names to predefine in the preprocessor for this target machine.  */
+
+#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \
+-Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)"
+
+/* Tell the assembler to assume that all undefined names are external.
+
+   Don't do this until the fixed IBM assembler is more generally available.
+   When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL,
+   ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no
+   longer be needed.  Also, the extern declaration of mcount in ASM_FILE_START
+   will no longer be needed.  */
+
+/* #define ASM_SPEC "-u %(asm_cpu)" */
+
+/* Default location of syscalls.exp under AIX */
+#ifndef CROSS_COMPILE
+#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
+#else
+#define LINK_SYSCALLS_SPEC ""
+#endif
+
+/* Default location of libg.exp under AIX */
+#ifndef CROSS_COMPILE
+#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
+#else
+#define LINK_LIBG_SPEC ""
+#endif
+
+/* Define the options for the binder: Start text at 512, align all segments
+   to 512 bytes, and warn if there is text relocation.
+
+ The -bhalt:4 option supposedly changes the level at which ld will abort,
+   but it also suppresses warnings about multiply defined symbols and is
+   used by the AIX cc command.  So we use it here.
+
+   -bnodelcsect undoes a poor choice of default relating to multiply-defined
+   csects.  See AIX documentation for more information about this.
+
+ -bM:SRE tells the linker that the output file is Shared REusable.  Note
+   that to actually build a shared library you will also need to specify an
+   export list with the -Wl,-bE option.  */
+
+#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
+%{static:-bnso %(link_syscalls) } \
+%{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
+
+/* Profiled library versions are used by linking with special directories.  */
+#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
+%{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
+
+/* Define the extra sections we need.  We define three: one is the read-only
+   data section which is used for constants.  This is a csect whose name is
+   derived from the name of the input file.  The second is for initialized
+   global variables.  This is a csect whose name is that of the variable.
+   The third is the TOC.  */
+
+#define EXTRA_SECTIONS \
+   read_only_data, private_data, read_only_private_data, toc, bss
+
+/* Define the routines to implement these extra sections.
+   BIGGEST_ALIGNMENT is 64, so align the sections that much.  */
+
+#define EXTRA_SECTION_FUNCTIONS                                \
+                                                       \
+void                                                   \
+read_only_data_section ()                              \
+{                                                      \
+  if (in_section != read_only_data)                    \
+    {                                                  \
+      fprintf (asm_out_file, "\t.csect %s[RO],3\n",    \
+              xcoff_read_only_section_name);           \
+      in_section = read_only_data;                     \
+    }                                                  \
+}                                                      \
+                                                       \
+void                                                   \
+private_data_section ()                                        \
+{                                                      \
+  if (in_section != private_data)                      \
+    {                                                  \
+      fprintf (asm_out_file, "\t.csect %s[RW],3\n",    \
+              xcoff_private_data_section_name);        \
+      in_section = private_data;                       \
+    }                                                  \
+}                                                      \
+                                                       \
+void                                                   \
+read_only_private_data_section ()                      \
+{                                                      \
+  if (in_section != read_only_private_data)            \
+    {                                                  \
+      fprintf (asm_out_file, "\t.csect %s[RO],3\n",    \
+              xcoff_private_data_section_name);        \
+      in_section = read_only_private_data;             \
+    }                                                  \
+}                                                      \
+                                                       \
+void                                                   \
+toc_section ()                                         \
+{                                                      \
+  if (TARGET_MINIMAL_TOC)                              \
+    {                                                  \
+      /* toc_section is always called at least once from ASM_FILE_START, \
+        so this is guaranteed to always be defined once and only once   \
+        in each file.  */                                               \
+      if (! toc_initialized)                           \
+       {                                               \
+         fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);  \
+         fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \
+         toc_initialized = 1;                          \
+       }                                               \
+                                                       \
+      if (in_section != toc)                           \
+       fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",    \
+                (TARGET_32BIT ? "" : ",3"));           \
+    }                                                  \
+  else                                                 \
+    {                                                  \
+      if (in_section != toc)                           \
+        fputs ("\t.toc\n", asm_out_file);              \
+    }                                                  \
+  in_section = toc;                                    \
+}
+
+/* Define the name of our readonly data section.  */
+
+#define READONLY_DATA_SECTION read_only_data_section
+
+/* Select the section for an initialized data object.
+
+   On the RS/6000, we have a special section for all variables except those
+   that are static.  */
+
+#define SELECT_SECTION(EXP,RELOC)                      \
+{                                                      \
+  if ((TREE_CODE (EXP) == STRING_CST                   \
+       && ! flag_writable_strings)                     \
+      || (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'd'     \
+         && TREE_READONLY (EXP) && ! TREE_THIS_VOLATILE (EXP) \
+         && DECL_INITIAL (EXP)                         \
+         && (DECL_INITIAL (EXP) == error_mark_node     \
+             || TREE_CONSTANT (DECL_INITIAL (EXP)))    \
+         && ! (RELOC)))                                \
+    {                                                  \
+      if (TREE_PUBLIC (EXP))                           \
+        read_only_data_section ();                     \
+      else                                             \
+        read_only_private_data_section ();             \
+    }                                                  \
+  else                                                 \
+    {                                                  \
+      if (TREE_PUBLIC (EXP))                           \
+        data_section ();                               \
+      else                                             \
+        private_data_section ();                       \
+    }                                                  \
+}
+
+/* Select section for constant in constant pool.
+
+   On RS/6000, all constants are in the private read-only data area.
+   However, if this is being placed in the TOC it must be output as a
+   toc entry.  */
+
+#define SELECT_RTX_SECTION(MODE, X)            \
+{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X))     \
+    toc_section ();                            \
+  else                                         \
+    read_only_private_data_section ();         \
+}
+
+/* Indicate that jump tables go in the text section.  */
+
+#define JUMP_TABLES_IN_TEXT_SECTION 1
+
+/* Enable AIX XL compiler calling convention breakage compatibility.  */
+#undef TARGET_XL_CALL
+#define MASK_XL_CALL           0x40000000
+#define        TARGET_XL_CALL          (target_flags & MASK_XL_CALL)
+#undef  SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES             \
+  {"xl-call",          MASK_XL_CALL,                                   \
+   "Always pass floating-point arguments in memory" },                 \
+  {"no-xl-call",       - MASK_XL_CALL,                                 \
+   "Don't always pass floating-point arguments in memory" },           \
+  SUBSUBTARGET_SWITCHES
+#define SUBSUBTARGET_SWITCHES 
+
+/* Define any extra SPECS that the compiler needs to generate.  */
+#undef  SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS                                          \
+  { "link_syscalls",            LINK_SYSCALLS_SPEC },                  \
+  { "link_libg",                LINK_LIBG_SPEC }
+
+/* FP save and restore routines.  */
+#define        SAVE_FP_PREFIX "._savef"
+#define SAVE_FP_SUFFIX ""
+#define        RESTORE_FP_PREFIX "._restf"
+#define RESTORE_FP_SUFFIX ""
+
+/* Define cutoff for using external functions to save floating point.  */
+#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
+
+/* Function name to call to do profiling.  */
+#define RS6000_MCOUNT ".__mcount"
+
+/* AIX always has a TOC.  */
+#define TARGET_NO_TOC          0
+#define        TARGET_TOC              1
+
+/* AIX allows r13 to be used.  */
+#define FIXED_R13 0
+
+/* This outputs NAME to FILE up to the first null or '['.  */
+
+#define RS6000_OUTPUT_BASENAME(FILE, NAME)     \
+  {                                            \
+    const char *_p;                            \
+                                               \
+    STRIP_NAME_ENCODING (_p, (NAME));          \
+    assemble_name ((FILE), _p);                        \
+  }
+
+/* This is how to output the definition of a user-level label named NAME,
+   such as the label on a static function or variable NAME.  */
+
+#define ASM_OUTPUT_LABEL(FILE,NAME)    \
+  do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+/* This is how to output a command to make the user-level label named NAME
+   defined for reference from other files.  */
+
+#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
+  do { fputs ("\t.globl ", FILE);      \
+       RS6000_OUTPUT_BASENAME (FILE, NAME); putc ('\n', FILE);} while (0)
+
+/* Remove any trailing [DS] or the like from the symbol name.  */
+
+#define STRIP_NAME_ENCODING(VAR,NAME)                  \
+  do                                                   \
+    {                                                  \
+      const char *_name = (NAME);                      \
+      size_t _len;                                     \
+      if (*_name == '*')                               \
+        _name++;                                       \
+      _len = strlen (_name);                           \
+      if (_name[_len - 1] != ']')                      \
+       (VAR) = _name;                                  \
+      else                                             \
+       {                                               \
+         char *_new_name = (char *) alloca (_len + 1); \
+         strcpy (_new_name, _name);                    \
+         _new_name[_len - 4] = '\0';                   \
+         (VAR) = _new_name;                            \
+       }                                               \
+    }                                                  \
+  while (0)
+
+/* Output at beginning of assembler file.
+
+   Initialize the section names for the RS/6000 at this point.
+
+   Specify filename, including full path, to assembler.
+
+   We want to go into the TOC section so at least one .toc will be emitted.
+   Also, in order to output proper .bs/.es pairs, we need at least one static
+   [RW] section emitted.
+
+   We then switch back to text to force the gcc2_compiled. label and the space
+   allocated after it (when profiling) into the text section.
+
+   Finally, declare mcount when profiling to make the assembler happy.  */
+
+#define ASM_FILE_START(FILE)                                   \
+{                                                              \
+  rs6000_gen_section_name (&xcoff_bss_section_name,            \
+                          main_input_filename, ".bss_");       \
+  rs6000_gen_section_name (&xcoff_private_data_section_name,   \
+                          main_input_filename, ".rw_");        \
+  rs6000_gen_section_name (&xcoff_read_only_section_name,      \
+                          main_input_filename, ".ro_");        \
+                                                               \
+  fprintf (FILE, "\t.file\t\"%s\"\n", main_input_filename);    \
+  if (TARGET_64BIT)                                            \
+    fputs ("\t.machine\t\"ppc64\"\n", FILE);                   \
+  toc_section ();                                              \
+  if (write_symbols != NO_DEBUG)                               \
+    private_data_section ();                                   \
+  text_section ();                                             \
+  if (profile_flag)                                            \
+    fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT);           \
+  rs6000_file_start (FILE, TARGET_CPU_DEFAULT);                        \
+}
+
+/* Output at end of assembler file.
+
+   On the RS/6000, referencing data should automatically pull in text.  */
+
+#define ASM_FILE_END(FILE)                                     \
+{                                                              \
+  text_section ();                                             \
+  fputs ("_section_.text:\n", FILE);                           \
+  data_section ();                                             \
+  fputs (TARGET_32BIT                                          \
+        ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", FILE); \
+}
+
+/* This macro produces the initial definition of a function name.
+   On the RS/6000, we need to place an extra '.' in the function name and
+   output the function descriptor.
+
+   The csect for the function will have already been created by the
+   `text_section' call previously done.  We do have to go back to that
+   csect, however.
+
+   The third and fourth parameters to the .function pseudo-op (16 and 044)
+   are placeholders which no longer have any use.  */
+
+#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)              \
+{ if (TREE_PUBLIC (DECL))                                      \
+    {                                                          \
+      fputs ("\t.globl .", FILE);                              \
+      RS6000_OUTPUT_BASENAME (FILE, NAME);                     \
+      putc ('\n', FILE);                                       \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      fputs ("\t.lglobl .", FILE);                             \
+      RS6000_OUTPUT_BASENAME (FILE, NAME);                     \
+      putc ('\n', FILE);                                       \
+    }                                                          \
+  fputs ("\t.csect ", FILE);                                   \
+  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
+  fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE);          \
+  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
+  fputs (":\n", FILE);                                         \
+  fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE);     \
+  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
+  fputs (", TOC[tc0], 0\n", FILE);                             \
+  fputs (TARGET_32BIT                                          \
+        ? "\t.csect .text[PR]\n." : "\t.csect .text[PR],3\n.", FILE); \
+  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
+  fputs (":\n", FILE);                                         \
+  if (write_symbols == XCOFF_DEBUG)                            \
+    xcoffout_declare_function (FILE, DECL, NAME);              \
+}
+
+/* This is how to output a reference to a user-level label named NAME.
+   `assemble_name' uses this.  */
+
+#define ASM_OUTPUT_LABELREF(FILE,NAME) \
+  fputs (NAME, FILE)
+
+/* This says how to output an external.  */
+
+#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
+{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
+  if ((TREE_CODE (DECL) == VAR_DECL            \
+       || TREE_CODE (DECL) == FUNCTION_DECL)   \
+      && (NAME)[strlen (NAME) - 1] != ']')     \
+    {                                          \
+      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
+      strcpy (_name, XSTR (_symref, 0));       \
+      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
+      XSTR (_symref, 0) = _name;               \
+    }                                          \
+}
+
+/* This is how to output an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.  */
+
+#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)     \
+  fprintf (FILE, "%s..%d:\n", PREFIX, NUM)
+
+/* This is how to output an internal label prefix.  rs6000.c uses this
+   when generating traceback tables.  */
+
+#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX)   \
+  fprintf (FILE, "%s..", PREFIX)
+
+/* This is how to output a label for a jump table.  Arguments are the same as
+   for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+   passed. */
+
+#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)       \
+{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+
+/* This is how to store into the string LABEL
+   the symbol_ref name of an internal numbered label where
+   PREFIX is the class of label and NUM is the number within the class.
+   This is suitable for output with `assemble_name'.  */
+
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
+  sprintf (LABEL, "*%s..%d", PREFIX, NUM)
+
+/* This is how to output an assembler line to define N characters starting
+   at P to FILE.  */
+
+#define ASM_OUTPUT_ASCII(FILE, P, N)  output_ascii ((FILE), (P), (N))
+
+/* This is how to advance the location counter by SIZE bytes.  */
+
+#define ASM_OUTPUT_SKIP(FILE,SIZE)  \
+  fprintf (FILE, "\t.space %d\n", (SIZE))
+
+/* This says how to output an assembler line
+   to define a global common symbol.  */
+
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \
+  do { fputs (".comm ", (FILE));                       \
+       RS6000_OUTPUT_BASENAME ((FILE), (NAME));                \
+       if ( (SIZE) > 4)                                        \
+         fprintf ((FILE), ",%d,3\n", (SIZE));          \
+       else                                            \
+        fprintf( (FILE), ",%d\n", (SIZE));             \
+  } while (0)
+
+/* These are various definitions for DWARF output.  They could just
+   use '.long' or '.word', but that aligns to a 4-byte boundary which
+   is not what is required.  So we define a million macros...  */
+
+#define ASM_OUTPUT_DWARF_ADDR_VAR(FILE, LABEL, LENGTH) \
+ do {   fprintf ((FILE), "\t.vbyte\t%d,", LENGTH);     \
+        assemble_name (FILE, LABEL);                   \
+  } while (0)
+
+#define ASM_OUTPUT_DWARF_DELTA_VAR(FILE, LABEL1, LABEL2, LENGTH)       \
+ do {   fprintf ((FILE), "\t.vbyte\t%d,", LENGTH);                     \
+        assemble_name (FILE, LABEL1);                                  \
+        fprintf (FILE, "-");                                           \
+        assemble_name (FILE, LABEL2);                                  \
+  } while (0)
+
+#define ASM_OUTPUT_DWARF_DELTA2(FILE, LABEL1, LABEL2)  \
+ ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2, 2)
+
+#define ASM_OUTPUT_DWARF_DELTA4(FILE, LABEL1, LABEL2)  \
+ ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2, 4)
+
+#define ASM_OUTPUT_DWARF_DELTA(FILE, LABEL1, LABEL2)                   \
+ ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2, DWARF_OFFSET_SIZE)
+
+#define ASM_OUTPUT_DWARF_ADDR_DELTA(FILE, LABEL1, LABEL2)      \
+ ASM_OUTPUT_DWARF_DELTA_VAR (FILE, LABEL1, LABEL2,             \
+                            POINTER_SIZE / BITS_PER_UNIT)
+
+#define ASM_OUTPUT_DWARF_ADDR(FILE, LABEL)                             \
+ ASM_OUTPUT_DWARF_ADDR_VAR (FILE, LABEL, POINTER_SIZE / BITS_PER_UNIT)
+
+#define ASM_OUTPUT_DWARF_DATA4(FILE, VALUE)                    \
+  fprintf ((FILE), "\t.vbyte\t4,0x%x", (unsigned) (VALUE))
+
+#define ASM_OUTPUT_DWARF_DATA2(FILE, VALUE)                    \
+  fprintf ((FILE), "\t.vbyte\t2,0x%x", (unsigned) (VALUE))
+
+#define ASM_OUTPUT_DWARF_OFFSET4(FILE, LABEL)  \
+ ASM_OUTPUT_DWARF_ADDR_VAR (FILE, LABEL, 4)
+
+#define ASM_OUTPUT_DWARF_OFFSET(FILE, LABEL)                   \
+ ASM_OUTPUT_DWARF_ADDR_VAR (FILE, LABEL, DWARF_OFFSET_SIZE)
+
+/* dwarf2out keys off this, but we don't have to have a real definition.  */
+#define UNALIGNED_INT_ASM_OP bite_me
+
+/* Output before instructions.
+   Text section for 64-bit target may contain 64-bit address jump table.  */
+#define TEXT_SECTION_ASM_OP (TARGET_32BIT \
+                             ? "\t.csect .text[PR]" : "\t.csect .text[PR],3")
+
+/* Output before writable data.
+   Align entire section to BIGGEST_ALIGNMENT.  */
+#define DATA_SECTION_ASM_OP "\t.csect .data[RW],3"
+
+/* __throw will restore its own return address to be the same as the
+   return address of the function that the throw is being made to.
+   This is unfortunate, because we want to check the original
+   return address to see if we need to restore the TOC.
+   So we have to squirrel it away with this.  */
+#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+
index 46bd03c..34d3628 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 running AIX version 3.1.
-   Copyright (C) 1993,1997 Free Software Foundation, Inc.
+   Copyright (C) 1993,1997, 2000 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@nyu.edu)
 
 This file is part of GNU CC.
@@ -22,6 +22,45 @@ Boston, MA 02111-1307, USA.  */
 
 
 #include "rs6000/rs6000.h"
+#include "rs6000/aix.h"
+
+/* Output something to declare an external symbol to the assembler.  Most
+   assemblers don't need this.
+
+   If we haven't already, add "[RW]" (or "[DS]" for a function) to the
+   name.  Normally we write this out along with the name.  In the few cases
+   where we can't, it gets stripped off.  */
+
+#undef ASM_OUTPUT_EXTERNAL
+#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
+{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
+  if ((TREE_CODE (DECL) == VAR_DECL            \
+       || TREE_CODE (DECL) == FUNCTION_DECL)   \
+      && (NAME)[strlen (NAME) - 1] != ']')     \
+    {                                          \
+      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
+      strcpy (_name, XSTR (_symref, 0));       \
+      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
+      XSTR (_symref, 0) = _name;               \
+    }                                          \
+  fputs ("\t.extern ", FILE);                  \
+  assemble_name (FILE, XSTR (_symref, 0));     \
+  if (TREE_CODE (DECL) == FUNCTION_DECL)       \
+    {                                          \
+      fputs ("\n\t.extern .", FILE);           \
+      RS6000_OUTPUT_BASENAME (FILE, XSTR (_symref, 0));        \
+    }                                          \
+  putc ('\n', FILE);                           \
+}
+
+/* Similar, but for libcall.  We only have to worry about the function name,
+   not that of the descriptor. */
+
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+{ fputs ("\t.extern .", FILE);                 \
+  assemble_name (FILE, XSTR (FUN, 0));         \
+  putc ('\n', FILE);                           \
+}
 
 /* AIX 3.2 defined _AIX32, but older versions do not.  */
 #undef CPP_PREDEFINES
index 9659794..f2b9386 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 POWER running AIX version 3.x with the fixed assembler.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
    Contributed by Jason Merrill (jason@cygnus.com).
 
 This file is part of GNU CC.
@@ -21,15 +21,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
-/* Enable AIX XL compiler calling convention breakage compatibility.  */
-#define MASK_XL_CALL           0x40000000
-#define        TARGET_XL_CALL          (target_flags & MASK_XL_CALL)
-#undef  SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES             \
-  {"xl-call",          MASK_XL_CALL},  \
-  {"no-xl-call",       - MASK_XL_CALL},
-
 #include "rs6000/rs6000.h"
+#include "rs6000/aix.h"
 
 /* Tell the assembler to assume that all undefined names are external.  */
 
@@ -68,21 +61,3 @@ Boston, MA 02111-1307, USA.  */
    %{mcpu=common: milli.exp%s} \
    %{shared:-bM:SRE}"
 #endif
-
-/* These are not necessary when we pass -u to the assembler, and undefining
-   them saves a great deal of space in object files.  */
-
-#undef ASM_OUTPUT_EXTERNAL
-#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
-{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
-  if ((TREE_CODE (DECL) == VAR_DECL            \
-       || TREE_CODE (DECL) == FUNCTION_DECL)   \
-      && (NAME)[strlen (NAME) - 1] != ']')     \
-    {                                          \
-      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
-      strcpy (_name, XSTR (_symref, 0));       \
-      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
-      XSTR (_symref, 0) = _name;               \
-    }                                          \
-}
index e4a731c..7ab7eed 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 POWER running AIX version 4.1.
-   Copyright (C) 1994, 1995, 1996, 1998, 1998, 1999
+   Copyright (C) 1994, 95, 1996, 1997, 1998, 1999, 2000
    Free Software Foundation, Inc.
    Contributed by David Edelsohn (edelsohn@gnu.org).
 
@@ -22,51 +22,19 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
-/* Enable AIX XL compiler calling convention breakage compatibility.  */
-#define MASK_XL_CALL           0x40000000
-#define        TARGET_XL_CALL          (target_flags & MASK_XL_CALL)
-#undef  SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES             \
-  {"xl-call",          MASK_XL_CALL},  \
-  {"no-xl-call",       - MASK_XL_CALL}, \
-  {"threads",          0},             \
-  {"pe",               0},
-
 #include "rs6000/rs6000.h"
+#include "rs6000/aix.h"
+
+#undef  SUBSUBTARGET_SWITCHES
+#define SUBSUBTARGET_SWITCHES          \
+  {"threads",          0,                                              \
+   "Use the thread library and reentrant C library" },                 \
+  {"pe",               0,                                              \
+   "Support message passing with the Parallel Environment" },
 
 #undef ASM_SPEC
 #define ASM_SPEC "-u %(asm_cpu)"
 
-/* Common ASM definitions used by ASM_SPEC amonst the various targets
-   for handling -mcpu=xxx switches.  */
-#undef ASM_CPU_SPEC
-#define ASM_CPU_SPEC \
-"%{!mcpu*: \
-  %{mpower: %{!mpower2: -mpwr}} \
-  %{mpower2: -mpwr2} \
-  %{mpowerpc*: -mppc} \
-  %{!mpower*: %{!mpowerpc*: %(asm_default)}}} \
-%{mcpu=common: -mcom} \
-%{mcpu=power: -mpwr} \
-%{mcpu=power2: -mpwr2} \
-%{mcpu=powerpc: -mppc} \
-%{mcpu=rios: -mpwr} \
-%{mcpu=rios1: -mpwr} \
-%{mcpu=rios2: -mpwr2} \
-%{mcpu=rsc: -mpwr} \
-%{mcpu=rsc1: -mpwr} \
-%{mcpu=403: -mppc} \
-%{mcpu=505: -mppc} \
-%{mcpu=601: -m601} \
-%{mcpu=602: -mppc} \
-%{mcpu=603: -m603} \
-%{mcpu=603e: -m603} \
-%{mcpu=604: -m604} \
-%{mcpu=604e: -m604} \
-%{mcpu=620: -mppc} \
-%{mcpu=821: -mppc} \
-%{mcpu=860: -mppc}"
-
 #undef ASM_DEFAULT_SPEC
 #define ASM_DEFAULT_SPEC "-mcom"
 
@@ -80,35 +48,6 @@ Boston, MA 02111-1307, USA.  */
    %{mthreads: -D_THREAD_SAFE}\
    %(cpp_cpu)"
 
-/* Common CPP definitions used by CPP_SPEC among the various targets
-   for handling -mcpu=xxx switches.  */
-#undef CPP_CPU_SPEC
-#define CPP_CPU_SPEC \
-"%{!mcpu*: \
-  %{mpower: %{!mpower2: -D_ARCH_PWR}} \
-  %{mpower2: -D_ARCH_PWR2} \
-  %{mpowerpc*: -D_ARCH_PPC} \
-  %{!mpower*: %{!mpowerpc*: %(cpp_default)}}} \
-%{mcpu=common: -D_ARCH_COM} \
-%{mcpu=power: -D_ARCH_PWR} \
-%{mcpu=power2: -D_ARCH_PWR2} \
-%{mcpu=powerpc: -D_ARCH_PPC} \
-%{mcpu=rios: -D_ARCH_PWR} \
-%{mcpu=rios1: -D_ARCH_PWR} \
-%{mcpu=rios2: -D_ARCH_PWR2} \
-%{mcpu=rsc: -D_ARCH_PWR} \
-%{mcpu=rsc1: -D_ARCH_PWR} \
-%{mcpu=403: -D_ARCH_PPC} \
-%{mcpu=505: -D_ARCH_PPC} \
-%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
-%{mcpu=602: -D_ARCH_PPC} \
-%{mcpu=603: -D_ARCH_PPC} \
-%{mcpu=603e: -D_ARCH_PPC} \
-%{mcpu=604: -D_ARCH_PPC} \
-%{mcpu=620: -D_ARCH_PPC} \
-%{mcpu=821: -D_ARCH_PPC} \
-%{mcpu=860: -D_ARCH_PPC}"
-
 #undef CPP_DEFAULT_SPEC
 #define CPP_DEFAULT_SPEC "-D_ARCH_COM"
 
@@ -130,24 +69,6 @@ Boston, MA 02111-1307, USA.  */
 #undef MULTILIB_DEFAULTS
 #define        MULTILIB_DEFAULTS { "mcpu=common" }
 
-/* These are not necessary when we pass -u to the assembler, and undefining
-   them saves a great deal of space in object files.  */
-
-#undef ASM_OUTPUT_EXTERNAL
-#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
-{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
-  if ((TREE_CODE (DECL) == VAR_DECL            \
-       || TREE_CODE (DECL) == FUNCTION_DECL)   \
-      && (NAME)[strlen (NAME) - 1] != ']')     \
-    {                                          \
-      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
-      strcpy (_name, XSTR (_symref, 0));       \
-      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
-      XSTR (_symref, 0) = _name;               \
-    }                                          \
-}
-
 #undef LIB_SPEC
 #define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
    %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}}\
index 8b0c6fb..3822c0a 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 POWER running AIX version 4.3.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    Contributed by David Edelsohn (edelsohn@gnu.org).
 
 This file is part of GNU CC.
@@ -21,17 +21,20 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
-/* Enable AIX XL compiler calling convention breakage compatibility.  */
-#define MASK_XL_CALL           0x40000000
-#define        TARGET_XL_CALL          (target_flags & MASK_XL_CALL)
-#undef  SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES                                     \
-  {"aix64",            MASK_64BIT | MASK_POWERPC64 | MASK_POWERPC}, \
-  {"aix32",            - (MASK_64BIT | MASK_POWERPC64)},       \
-  {"xl-call",          MASK_XL_CALL},                          \
-  {"no-xl-call",       - MASK_XL_CALL},                        \
-  {"threads",          0},                                     \
-  {"pe",               0},
+#include "rs6000/rs6000.h"
+#include "rs6000/aix.h"
+
+/* AIX 4.3 and above support 64-bit executables.  */
+#undef  SUBSUBTARGET_SWITCHES
+#define SUBSUBTARGET_SWITCHES                                  \
+  {"aix64",            MASK_64BIT | MASK_POWERPC64 | MASK_POWERPC,     \
+   "Compile for 64-bit pointers" },                                    \
+  {"aix32",            - (MASK_64BIT | MASK_POWERPC64),                \
+   "Compile for 32-bit pointers" },                                    \
+  {"threads",          0,                                              \
+   "Use the thread library and reentrant C library" },                 \
+  {"pe",               0,                                              \
+   "Support message passing with the Parallel Environment" },
 
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
@@ -57,8 +60,6 @@ do {                                                                  \
     }                                                                  \
 } while (0);
 
-#include "rs6000/rs6000.h"
-
 #undef ASM_SPEC
 #define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)"
 
@@ -161,24 +162,6 @@ do {                                                                       \
 #undef MULTILIB_DEFAULTS
 #define        MULTILIB_DEFAULTS { "mcpu=common" }
 
-/* These are not necessary when we pass -u to the assembler, and undefining
-   them saves a great deal of space in object files.  */
-
-#undef ASM_OUTPUT_EXTERNAL
-#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
-{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
-  if ((TREE_CODE (DECL) == VAR_DECL            \
-       || TREE_CODE (DECL) == FUNCTION_DECL)   \
-      && (NAME)[strlen (NAME) - 1] != ']')     \
-    {                                          \
-      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
-      strcpy (_name, XSTR (_symref, 0));       \
-      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
-      XSTR (_symref, 0) = _name;               \
-    }                                          \
-}
-
 #undef LIB_SPEC
 #define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
    %{p:-L/lib/profiled -L/usr/lib/profiled}\
@@ -214,7 +197,6 @@ do {                                                                        \
 #undef RS6000_CALL_GLUE
 #define RS6000_CALL_GLUE "{cror 31,31,31|nop}"
 
-#if 0
 /* AIX 4.2 and above provides initialization and finalization function
    support from linker command line.  */
 #undef HAS_INIT_SECTION
@@ -222,4 +204,3 @@ do {                                                                        \
 
 #undef LD_INIT_SWITCH
 #define LD_INIT_SWITCH "-binitfini"
-#endif
index 851601f..6643691 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for BeOS.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
    Contributed by Fred Fish (fnf@cygnus.com), based on aix41.h
    from David Edelsohn (edelsohn@npac.syr.edu).
 
@@ -21,6 +21,9 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
+#include "rs6000/rs6000.h"
+#include "rs6000/aix.h"
+
 /* Enable AIX XL compiler calling convention breakage compatibility.  */
 #define MASK_XL_CALL           0x40000000
 #define        TARGET_XL_CALL          (target_flags & MASK_XL_CALL)
@@ -31,8 +34,6 @@ Boston, MA 02111-1307, USA.  */
   {"threads",          0},             \
   {"pe",               0},
 
-#include "rs6000/rs6000.h"
-
 #undef ASM_SPEC
 #define ASM_SPEC "-u %(asm_cpu)"
 
@@ -79,24 +80,6 @@ Boston, MA 02111-1307, USA.  */
 #undef MULTILIB_DEFAULTS
 #define        MULTILIB_DEFAULTS { "mcpu=powerpc" }
 
-/* These are not necessary when we pass -u to the assembler, and undefining
-   them saves a great deal of space in object files.  */
-
-#undef ASM_OUTPUT_EXTERNAL
-#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
-{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
-  if ((TREE_CODE (DECL) == VAR_DECL            \
-       || TREE_CODE (DECL) == FUNCTION_DECL)   \
-      && (NAME)[strlen (NAME) - 1] != ']')     \
-    {                                          \
-      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
-      strcpy (_name, XSTR (_symref, 0));       \
-      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
-      XSTR (_symref, 0) = _name;               \
-    }                                          \
-}
-
 /* These empty definitions get rid of the attempt to link in crt0.o
    and any libraries like libc.a.
    On BeOS the ld executable is actually a linker front end that first runs
diff --git a/gcc/config/rs6000/cygwin.h b/gcc/config/rs6000/cygwin.h
deleted file mode 100644 (file)
index 0ed448b..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Operating system specific defines to be used when targeting GCC for
-   hosting on Windows NT 3.x, using the Cygnus API 
-
-   This is different to the winnt.h file, since that is used
-   to build GCC for use with a windows style library and tool
-   set, winnt.h uses the Microsoft tools to do that.
-
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC 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.
-
-GNU CC 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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-
-/* Ugly hack */
-#include "rs6000/win-nt.h"
-
-
-#ifdef CPP_PREDEFINES
-#undef CPP_PREDEFINES
-#endif
-
-#define        CPP_PREDEFINES "-D_WIN32 -DWINNT -D__CYGWIN__ -D__CYGWIN32__ -DPOSIX \
-  -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
-
-#undef CPP_SPEC
-#define CPP_SPEC "-remap %{posix: -D_POSIX_SOURCE} %(cpp_cpu)"
-
-/* We have to dynamic link to get to the system DLLs.  All of libc, libm and
-   the Unix stuff is in cygwin.dll.  The import library is called
-   'libcygwin.a'.  For Windows applications, include more libraries, but
-   always include kernel32.  We'd like to specific subsystem windows to
-   ld, but that doesn't work just yet.  */
-
-#undef LIB_SPEC
-#define LIB_SPEC "-lcygwin %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32"
-
-#undef LINK_SPEC
-#define        LINK_SPEC "%{v:-V}"
-
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC "crti%O%s crt0%O%s"
-
-#undef ENDFILE_SPEC
-#define        ENDFILE_SPEC "crtn%O%s"
-
-#define PTRDIFF_TYPE "int"
-#define WCHAR_UNSIGNED 1
-#define WCHAR_TYPE_SIZE 16
-#define WCHAR_TYPE "short unsigned int"
-
-#define DBX_DEBUGGING_INFO 
-#undef SDB_DEBUGGING_INFO 
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
index 6b753ca..40fc98e 100644 (file)
@@ -1,6 +1,6 @@
 # crti.s for eabi
 
-#   Copyright (C) 1996 Free Software Foundation, Inc.
+#   Copyright (C) 1996, 2000 Free Software Foundation, Inc.
 #   Written By Michael Meissner
 # 
 # This file is free software; you can redistribute it and/or modify it
@@ -102,6 +102,11 @@ __SBSS2_START__:
        .type   __EXCEPT_START__,@object
 __EXCEPT_START__:
 
+       .section ".eh_frame","aw"
+       .globl  __EH_FRAME_BEGIN__
+       .type   __EH_FRAME_BEGIN__,@object
+__EH_FRAME_BEGIN__:
+
 # Head of __init function used for static constructors in Solaris
        .section ".init","ax"
        .align 2
index 06e8956..d62e2fa 100644 (file)
@@ -1,6 +1,6 @@
 # crtn.s for eabi
 
-#   Copyright (C) 1996 Free Software Foundation, Inc.
+#   Copyright (C) 1996, 2000 Free Software Foundation, Inc.
 #   Written By Michael Meissner
 # 
 # This file is free software; you can redistribute it and/or modify it
@@ -94,6 +94,12 @@ __SBSS2_END__:
        .type   __EXCEPT_END__,@object
 __EXCEPT_END__:
 
+       .section ".eh_frame","aw"
+       .globl  __EH_FRAME_END__
+       .type   __EH_FRAME_END__,@object
+__EH_FRAME_END__:
+        .long   0
+
 # Tail of __init used for static constructors in Solaris
        .section ".init","ax"
        lwz 0,12(1)
index 2ff3c1a..9785a11 100644 (file)
@@ -1,7 +1,7 @@
 /* Stripped down support to run global constructors and destructors on
    embedded PowerPC systems.
 
-   Copyright (C) 1995 Free Software Foundation, Inc.
+   Copyright (C) 1995, 2000 Free Software Foundation, Inc.
    Contributed by Michael Meissner  (meissner@cygnus.com).
 
 This file is part of GNU CC.
@@ -28,65 +28,77 @@ Boston, MA 02111-1307, USA.  */
    This exception does not however invalidate any other reasons why
    the executable file might be covered by the GNU General Public License.  */
 
+#include "tm.h"
+#include "defaults.h"
+#include <stddef.h>
+#include "frame.h"
+#include "gbl-ctors.h"
 
-/*  Declare a pointer to void function type.  */
-
-typedef void (*func_ptr) (void);
+/* FIXME: This file should share code with all the other
+   constructor/destructor implementations in crtstuff.c and libgcc2.c.  */
 
 /* Declare the set of symbols use as begin and end markers for the lists
    of global object constructors and global object destructors.  */
 
-extern func_ptr __CTOR_LIST__[];
-extern func_ptr __CTOR_END__ [];
-extern func_ptr __DTOR_LIST__[];
-extern func_ptr __DTOR_END__ [];
+extern func_ptr __CTOR_LIST__[] asm ("__CTOR_LIST__");
+extern func_ptr __CTOR_END__ [] asm ("__CTOR_END__");
+extern func_ptr __DTOR_LIST__[] asm ("__DTOR_LIST__");
+extern func_ptr __DTOR_END__ [] asm ("__DTOR_END__");
+extern unsigned char __EH_FRAME_BEGIN__[] asm ("__EH_FRAME_BEGIN__");
 
 extern void __do_global_ctors (void);
-extern void __do_global_dtors (void);
 
 extern void __init (), __fini ();
 
-/* The Solaris linker seems to incorrectly relocate PC relative relocations
-   to a different section (ie, calls to __init, __fini), so avoid it by
-   using a function pointer.  */
-static void (*init_ptr) (void) = __init;
-static void (*fini_ptr) (void) = __fini;
-
 void (*__atexit)(func_ptr);
 
 /* Call all global constructors */
 void
 __do_global_ctors (void)
 {
-  func_ptr *ptr   = &__CTOR_END__[0] - 1;
-  func_ptr *start = &__CTOR_LIST__[0];
+  func_ptr *p = __CTOR_END__ - 1;
 
-  if (__atexit)
-    __atexit (__do_global_dtors);
+#ifdef EH_FRAME_SECTION
+  {
+    static struct object object;
+    __register_frame_info (__EH_FRAME_BEGIN__, &object);
+  }
+#endif
 
   /* Call the constructors collected in the .ctors section.  */
-  for ( ; ptr >= start; ptr--)
-    if (*ptr)
-      (*ptr)();
+  for ( ; p >= __CTOR_LIST__; p--)
+    if (*p)
+      (*p)();
+  
+  if (__atexit)
+    __atexit (__do_global_dtors);
 
   /* Call the initialization function in the .init section.  */
-  (*init_ptr) ();
+  __init ();
 }
 
 /* Call all global destructors */
 void
 __do_global_dtors (void)
 {
-  func_ptr *ptr   = &__DTOR_LIST__[0];
-  func_ptr *end   = &__DTOR_END__[0];
+  static func_ptr *p = __DTOR_LIST__ + 1;
+  static int completed = 0;
 
-  /* Call the termination function in the .fini section.  */
-  (*fini_ptr) ();
+  if (completed)
+    return;
 
-  /* Call the  destructors collected in the .dtors section.  Run
-     the destructors in reverse order.  */
-  for ( ; ptr < end; ptr++)
-    if (*ptr)
-      (*ptr)();
+  /* Call the termination function in the .fini section.  */
+  __fini ();
+
+  while (p < __DTOR_END__)
+    {
+      p++;
+      (*(p-1)) ();
+    }
+
+#ifdef EH_FRAME_SECTION_ASM_OP
+  if (__deregister_frame_info)
+    __deregister_frame_info (__EH_FRAME_BEGIN__);
+#endif
+  completed = 1;
 }
-
index 1c225ea..5293a07 100644 (file)
@@ -1,6 +1,6 @@
 /* Core target definitions for GNU compiler
    for IBM RS/6000 PowerPC targeted to embedded ELF systems.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GNU CC.
@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Invoke an initializer function to set up the GOT */
 #define NAME__MAIN "__eabi"
+#define INVOKE__main
 
 #undef TARGET_VERSION
 #define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
index e2fe633..5257be5 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for Rs6000 running LynxOS.
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
    Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com)
 
 This file is part of GNU CC.
@@ -96,7 +96,6 @@ do {                                                          \
 #undef OBJECT_FORMAT_ROSE
 #undef MD_EXEC_PREFIX
 #undef REAL_LD_FILE_NAME
-#undef REAL_NM_FILE_NAME
 #undef REAL_STRIP_FILE_NAME
 
 /* LynxOS doesn't have mcount. */
index 61133b9..622b972 100644 (file)
@@ -1,6 +1,6 @@
 /* Core target definitions for GNU compiler
    for IBM RS/6000 PowerPC running NetWare
-   Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1995, 1996, 1998, 2000 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GNU CC.
@@ -34,24 +34,11 @@ Boston, MA 02111-1307, USA.  */
 #undef PROCESSOR_DEFAULT
 #define PROCESSOR_DEFAULT PROCESSOR_PPC601
 
-/* Don't generate XCOFF debugging information.  */
-
-#undef XCOFF_DEBUGGING_INFO
-
-/* Don't use the COFF object file format.  */
-
-#undef OBJECT_FORMAT_COFF
-
 /* The XCOFF support uses weird symbol suffixes, which we don't want
    for ELF.  */
 
 #undef STRIP_NAME_ENCODING
 
-/* Don't bother to output .extern pseudo-ops.  They are not needed by
-   ELF assemblers.  */
-
-#undef ASM_OUTPUT_EXTERNAL
-
 /* Undefine some things which are defined by the generic svr4.h.  */
 
 #undef ASM_FILE_END
diff --git a/gcc/config/rs6000/nt-ci.asm b/gcc/config/rs6000/nt-ci.asm
deleted file mode 100644 (file)
index 67ca956..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-# crti.s for Windows NT
-
-#   Copyright (C) 1996 Free Software Foundation, Inc.
-#   Written By Michael Meissner
-# 
-# This file 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.
-# 
-# In addition to the permissions in the GNU General Public License, the
-# Free Software Foundation gives you unlimited permission to link the
-# compiled version of this file with other programs, and to distribute
-# those programs without any restriction coming from the use of this
-# file.  (The General Public License restrictions do apply in other
-# respects; for example, they cover modification of the file, and
-# distribution when not linked into another program.)
-# 
-# This file 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; see the file COPYING.  If not, write to
-# the Free Software Foundation, 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-# 
-#    As a special exception, if you link this library with files
-#    compiled with GCC to produce an executable, this does not cause
-#    the resulting executable to be covered by the GNU General Public License.
-#    This exception does not however invalidate any other reasons why
-#    the executable file might be covered by the GNU General Public License.
-# 
-
-# This file just supplies labeled starting points for the static constructors
-# and destructors.  It is linked in first before other modules.
-       .file   "crti.s"
-       .ident  "GNU C crti.s"
-
-       .section .ctors,"w"
-       .globl  __CTOR_LIST__
-__CTOR_LIST__:
-
-       .section .dtors,"w"
-       .globl  __DTOR_LIST__
-__DTOR_LIST__:
diff --git a/gcc/config/rs6000/nt-cn.asm b/gcc/config/rs6000/nt-cn.asm
deleted file mode 100644 (file)
index dd6daf2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-# crtn.s for Windows NT
-
-#   Copyright (C) 1996 Free Software Foundation, Inc.
-#   Written By Michael Meissner
-# 
-# This file 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.
-# 
-# In addition to the permissions in the GNU General Public License, the
-# Free Software Foundation gives you unlimited permission to link the
-# compiled version of this file with other programs, and to distribute
-# those programs without any restriction coming from the use of this
-# file.  (The General Public License restrictions do apply in other
-# respects; for example, they cover modification of the file, and
-# distribution when not linked into another program.)
-# 
-# This file 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; see the file COPYING.  If not, write to
-# the Free Software Foundation, 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-# 
-#    As a special exception, if you link this library with files
-#    compiled with GCC to produce an executable, this does not cause
-#    the resulting executable to be covered by the GNU General Public License.
-#    This exception does not however invalidate any other reasons why
-#    the executable file might be covered by the GNU General Public License.
-# 
-
-# This file just supplies labeled ending points for the static constructors
-# and destructors.  It is linked in last after other modules.
-       .file   "crtn.s"
-       .ident  "GNU C crtn.s"
-
-       .section .ctors,"w"
-       .globl  __CTOR_END__
-__CTOR_END__:
-
-       .section .dtors,"w"
-       .globl  __DTOR_END__
-__DTOR_END__:
diff --git a/gcc/config/rs6000/ntstack.asm b/gcc/config/rs6000/ntstack.asm
deleted file mode 100644 (file)
index aa4179e..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# Allocate stack for NT, inserting stack probes every 4k pages
-
-       .file   "ntstack.asm"
-
-#      Setup MS Structured-Exception-Handling
-       .pdata
-       .align 2
-       .ualong ..__allocate_stack,__allocate_stack.e,0,0,__allocate_stack.b
-
-#      Switch to the relocation section
-       .reldata
-       .globl __allocate_stack
-       .globl ..__allocate_stack
-__allocate_stack:
-       .ualong ..__allocate_stack,.toc
-
-       .text
-       .align 2
-..__allocate_stack:
-       .function       ..__allocate_stack
-__allocate_stack.b:
-       addi    3,3,15                  # round up to 16 byte alignment
-       lwz     0,0(1)                  # old stack link
-       rlwinm  3,3,0,0,28
-       srawi.  4,3,12                  # get # of pages to check
-       neg     3,3                     # negate so we can use stwux
-       bgt-    0,.Lcheck
-       stwux   0,1,3                   # small request, just decrement and return
-       blr
-
-.Lcheck:
-       mtctr   4                       # number of pages to check
-       mr      5,1                     # tmp pointer
-.Lloop:
-       lwzu    6,-4096(5)              # touch the page
-       bdnz+   .Lloop                  # and loop back
-
-       stwux   0,1,3                   # update stack pointer
-       blr
-
-__allocate_stack.e:
-FE_MOT_RESVD..__allocate_stack:
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
new file mode 100644 (file)
index 0000000..c633607
--- /dev/null
@@ -0,0 +1,162 @@
+/* Definitions of target machine for GNU compiler, for IBM RS/6000.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Declare functions in rs6000.c */
+
+#ifdef RTX_CODE
+
+#ifdef TREE_CODE
+extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int));
+extern void rs6000_va_start PARAMS ((int, tree, rtx));
+#endif /* TREE_CODE */
+
+extern struct rtx_def *rs6000_got_register PARAMS ((rtx));
+extern struct rtx_def *find_addr_reg PARAMS ((rtx));
+extern int any_operand PARAMS ((rtx, enum machine_mode));
+extern int short_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int u_short_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int non_short_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int gpc_reg_operand PARAMS ((rtx, enum machine_mode));
+extern int cc_reg_operand PARAMS ((rtx, enum machine_mode));
+extern int cc_reg_not_cr0_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_short_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_neg_short_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_u_short_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_u_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int got_operand PARAMS ((rtx, enum machine_mode));
+extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
+extern int num_insns_constant PARAMS ((rtx, enum machine_mode));
+extern int easy_fp_constant PARAMS ((rtx, enum machine_mode));
+extern int volatile_mem_operand PARAMS ((rtx, enum machine_mode));
+extern int offsettable_mem_operand PARAMS ((rtx, enum machine_mode));
+extern int mem_or_easy_const_operand PARAMS ((rtx, enum machine_mode));
+extern int add_operand PARAMS ((rtx, enum machine_mode));
+extern int non_add_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int non_logical_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int non_logical_u_cint_operand PARAMS ((rtx, enum machine_mode));
+extern int logical_operand PARAMS ((rtx, enum machine_mode));
+extern int logical_u_operand PARAMS ((rtx, enum machine_mode));
+extern int mask_operand PARAMS ((rtx, enum machine_mode));
+extern int mask64_operand PARAMS ((rtx, enum machine_mode));
+extern int and64_operand PARAMS ((rtx, enum machine_mode));
+extern int and_operand PARAMS ((rtx, enum machine_mode));
+extern int count_register_operand PARAMS ((rtx, enum machine_mode));
+extern int xer_operand PARAMS ((rtx, enum machine_mode));
+extern int reg_or_mem_operand PARAMS ((rtx, enum machine_mode));
+extern int lwa_operand PARAMS ((rtx, enum machine_mode));
+extern int call_operand PARAMS ((rtx, enum machine_mode));
+extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
+extern int input_operand PARAMS ((rtx, enum machine_mode));
+extern int small_data_operand PARAMS ((rtx, enum machine_mode));
+extern int constant_pool_expr_p PARAMS ((rtx));
+extern int toc_relative_expr_p PARAMS ((rtx));
+extern int expand_block_move PARAMS ((rtx[]));
+extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
+extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
+extern int branch_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int scc_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int trap_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int includes_lshift_p PARAMS ((rtx, rtx));
+extern int includes_rshift_p PARAMS ((rtx, rtx));
+extern int registers_ok_for_quad_peep PARAMS ((rtx, rtx));
+extern int addrs_ok_for_quad_peep PARAMS ((rtx, rtx));
+extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
+                                                     enum machine_mode, rtx));
+extern int ccr_bit PARAMS ((rtx, int));
+extern void print_operand PARAMS ((FILE *, rtx, int));
+extern void print_operand_address PARAMS ((FILE *, rtx));
+extern void output_toc PARAMS ((FILE *, rtx, int));
+extern int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+extern int rs6000_adjust_priority PARAMS ((rtx, int));
+extern void rs6000_initialize_trampoline PARAMS ((rtx, rtx, rtx));
+extern struct rtx_def *rs6000_longcall_ref PARAMS ((rtx));
+extern void rs6000_fatal_bad_address PARAMS ((rtx));
+extern int stmw_operation PARAMS ((rtx, enum machine_mode));
+extern int mtcrf_operation PARAMS ((rtx, enum machine_mode));
+extern int lmw_operation PARAMS ((rtx, enum machine_mode));
+extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
+extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
+extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
+extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx));
+#endif /* RTX_CODE */
+
+#ifdef TREE_CODE
+extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
+                                         tree, int));
+extern int function_arg_boundary PARAMS ((enum machine_mode, tree));
+extern struct rtx_def *function_arg PARAMS ((CUMULATIVE_ARGS *,
+                                            enum machine_mode, tree, int));
+extern int function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
+                                              enum machine_mode, tree, int));
+extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
+                                                  enum machine_mode,
+                                                  tree, int));
+extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
+                                           enum machine_mode, tree,
+                                           int *, int));
+extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree));
+extern void output_mi_thunk PARAMS ((FILE *, tree, int, tree));
+extern int rs6000_comp_type_attributes PARAMS ((tree, tree));
+extern int rs6000_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree));
+extern int rs6000_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
+extern void rs6000_set_default_type_attributes PARAMS ((tree));
+extern void rs6000_encode_section_info PARAMS ((tree));
+extern void rs6000_select_section PARAMS ((tree, int));
+#ifdef ARGS_SIZE_RTX
+/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
+extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
+#endif /* ARGS_SIZE_RTX */
+#endif /* TREE_CODE */
+
+extern void optimization_options PARAMS ((int, int));
+extern void rs6000_override_options PARAMS ((const char *));
+extern void rs6000_file_start PARAMS ((FILE *, const char *));
+extern struct rtx_def *rs6000_float_const PARAMS ((const char *,
+                                                  enum machine_mode));
+extern int direct_return PARAMS ((void));
+extern int get_issue_rate PARAMS ((void));
+extern union tree_node *rs6000_build_va_list PARAMS ((void));
+extern void rs6000_save_machine_status PARAMS ((struct function *));
+extern void rs6000_restore_machine_status PARAMS ((struct function *));
+extern void rs6000_init_expanders PARAMS ((void));
+extern int first_reg_to_save PARAMS ((void));
+extern int first_fp_reg_to_save PARAMS ((void));
+extern rs6000_stack_t *rs6000_stack_info PARAMS ((void));
+extern void output_prolog PARAMS ((FILE *, int));
+extern void output_epilog PARAMS ((FILE *, int));
+extern void output_ascii PARAMS ((FILE *, const char *, int));
+extern void rs6000_gen_section_name PARAMS ((char **, const char *,
+                                            const char *));
+extern void output_function_profiler PARAMS ((FILE *, int));
+extern int rs6000_trampoline_size PARAMS ((void));
+extern void toc_section PARAMS ((void));
+extern void sdata_section PARAMS ((void));
+extern void sdata2_section PARAMS ((void));
+extern void sbss_section PARAMS ((void));
+extern void private_data_section PARAMS ((void));
+extern int get_TOC_alias_set PARAMS ((void));
+extern int uses_TOC PARAMS ((void));
+extern void rs6000_emit_prologue PARAMS ((void));
+extern void rs6000_emit_load_toc_table PARAMS ((int));
+extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void));
+extern void rs6000_emit_epilogue PARAMS ((int));
+extern void debug_stack_info PARAMS ((rs6000_stack_t *));
index a408d7e..e792358 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines used for code generation on IBM RS/6000.
-   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 
+   2000 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GNU CC.
@@ -40,6 +40,8 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "toplev.h"
 #include "ggc.h"
+#include "hashtab.h"
+#include "tm_p.h"
 
 #ifndef TARGET_NO_PROTOTYPE
 #define TARGET_NO_PROTOTYPE 0
@@ -78,12 +80,11 @@ static int common_mode_defined;
 rtx rs6000_compare_op0, rs6000_compare_op1;
 int rs6000_compare_fp_p;
 
-#ifdef USING_SVR4_H
 /* Label number of label created for -mrelocatable, to call to so we can
    get the address of the GOT section */
 int rs6000_pic_labelno;
-int rs6000_pic_func_labelno;
 
+#ifdef USING_SVR4_H
 /* Which abi to adhere to */
 const char *rs6000_abi_name = RS6000_ABI_NAME;
 
@@ -92,6 +93,9 @@ enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
 
 /* Which small data model to use */
 const char *rs6000_sdata_name = (char *)0;
+
+/* Counter for labels which are to be placed in .fixup.  */
+int fixuplabelno = 0;
 #endif
 
 /* Whether a System V.4 varargs area was created.  */
@@ -100,11 +104,6 @@ int rs6000_sysv_varargs_p;
 /* ABI enumeration available for subtarget to use.  */
 enum rs6000_abi rs6000_current_abi;
 
-/* Offset & size for fpmem stack locations used for converting between
-   float and integral types.  */
-int rs6000_fpmem_offset;
-int rs6000_fpmem_size;
-
 /* Debug flags */
 const char *rs6000_debug_name;
 int rs6000_debug_stack;                /* debug stack applications */
@@ -112,9 +111,23 @@ int rs6000_debug_arg;              /* debug argument handling */
 
 /* Flag to say the TOC is initialized */
 int toc_initialized;
+char toc_label_name[10];
 
-static void rs6000_add_gc_roots PARAMS ((void));
+/* Alias set for saves and restores from the rs6000 stack.  */
+static int rs6000_sr_alias_set;
 
+static void rs6000_add_gc_roots PARAMS ((void));
+static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
+static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx));
+static void rs6000_emit_stack_tie PARAMS ((void));
+static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
+static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
+static unsigned rs6000_hash_constant PARAMS ((rtx));
+static unsigned toc_hash_function PARAMS ((const void *));
+static int toc_hash_eq PARAMS ((const void *, const void *));
+static int toc_hash_mark_entry PARAMS ((void *, void *));
+static void toc_hash_mark_table PARAMS ((void *));
+static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
 \f
 /* Default register names.  */
 char rs6000_reg_names[][8] =
@@ -129,7 +142,7 @@ char rs6000_reg_names[][8] =
      "24", "25", "26", "27", "28", "29", "30", "31",
      "mq", "lr", "ctr","ap",
       "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",
-  "fpmem"
+      "xer"
 };
 
 #ifdef TARGET_REGNAMES
@@ -145,7 +158,7 @@ static char alt_reg_names[][8] =
   "%f24",  "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
     "mq",    "lr",  "ctr",   "ap",
   "%cr0",  "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
"fpmem"
 "xer"
 };
 #endif
 \f
@@ -374,6 +387,12 @@ rs6000_override_options (default_cpu)
 
   /* Register global variables with the garbage collector.  */
   rs6000_add_gc_roots ();
+
+  /* Allocate an alias set for register saves & restores from stack.  */
+  rs6000_sr_alias_set = new_alias_set ();
+
+  if (TARGET_TOC) 
+    ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
 }
 
 void
@@ -496,24 +515,17 @@ count_register_operand(op, mode)
   return 0;
 }
 
-/* Returns 1 if op is memory location for float/int conversions that masquerades
-   as a register.  */
 int
-fpmem_operand(op, mode)
+xer_operand(op, mode)
      register rtx op;
      enum machine_mode mode ATTRIBUTE_UNUSED;
 {
   if (GET_CODE (op) != REG)
     return 0;
 
-  if (FPMEM_REGNO_P (REGNO (op)))
+  if (XER_REGNO_P (REGNO (op)))
     return 1;
 
-#if 0
-  if (REGNO (op) > FIRST_PSEUDO_REGISTER)
-    return 1;
-#endif
-
   return 0;
 }
 
@@ -560,8 +572,9 @@ gpc_reg_operand (op, mode)
 {
   return (register_operand (op, mode)
          && (GET_CODE (op) != REG
-             || (REGNO (op) >= 67 && !FPMEM_REGNO_P (REGNO (op)))
-             || REGNO (op) < 64));
+             || (REGNO (op) >= ARG_POINTER_REGNUM 
+                 && !XER_REGNO_P (REGNO (op)))
+             || REGNO (op) < MQ_REGNO));
 }
 
 /* Returns 1 if OP is either a pseudo-register or a register denoting a
@@ -641,6 +654,27 @@ reg_or_cint_operand (op, mode)
             || gpc_reg_operand (op, mode));
 }
 
+/* Return 1 is the operand is either a non-special register or ANY
+   32-bit unsigned constant integer.  */
+
+int
+reg_or_u_cint_operand (op, mode)
+    register rtx op;
+    enum machine_mode mode;
+{
+     return (gpc_reg_operand (op, mode)
+            || (GET_CODE (op) == CONST_INT
+#if HOST_BITS_PER_WIDE_INT != 32
+                && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+                && INTVAL (op) > 0)
+#if HOST_BITS_PER_WIDE_INT == 32
+            || (GET_CODE (op) == CONST_DOUBLE
+                && CONST_DOUBLE_HIGH (op) == 0)
+#endif
+        );
+}
+
 /* Return 1 if the operand is an operand that can be loaded via the GOT */
 
 int
@@ -685,10 +719,10 @@ num_insns_constant_wide (value)
       HOST_WIDE_INT low  = value & 0xffffffff;
       HOST_WIDE_INT high = value >> 32;
 
-      if (high == 0 && (low & 0x80000000) == 0)
+      if (high == 0 && (low & 0x80000000u) == 0)
        return 2;
 
-      else if (high == -1 && (low & 0x80000000) != 0)
+      else if (high == -1 && (low & 0x80000000u) != 0)
        return 2;
 
       else if (! low)
@@ -749,10 +783,10 @@ num_insns_constant (op, mode)
 
       else
        {
-         if (high == 0 && (low & 0x80000000) == 0)
+         if (high == 0 && (low & 0x80000000u) == 0)
            return num_insns_constant_wide (low);
 
-         else if (high == -1 && (low & 0x80000000) != 0)
+         else if (high == -1 && (low & 0x80000000u) != 0)
            return num_insns_constant_wide (low);
 
          else if (mask64_operand (op, mode))
@@ -917,10 +951,41 @@ logical_operand (op, mode)
 {
   return (gpc_reg_operand (op, mode)
          || (GET_CODE (op) == CONST_INT
+#if HOST_BITS_PER_WIDE_INT != 32
+             && INTVAL (op) > 0
+             && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+             && ((INTVAL (op) & GET_MODE_MASK (mode)
+                  & (~ (HOST_WIDE_INT) 0xffff)) == 0
+                 || (INTVAL (op) & GET_MODE_MASK (mode)
+                     & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0)));
+}
+
+/* Return 1 if the operand is a non-special register or a 32-bit constant
+   that can be used as the operand of an OR or XOR insn on the RS/6000.  */
+
+int
+logical_u_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  return (gpc_reg_operand (op, mode)
+         || (GET_CODE (op) == CONST_INT
+             && INTVAL (op) > 0
+#if HOST_BITS_PER_WIDE_INT != 32
+             && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
              && ((INTVAL (op) & GET_MODE_MASK (mode)
                   & (~ (HOST_WIDE_INT) 0xffff)) == 0
                  || (INTVAL (op) & GET_MODE_MASK (mode)
-                     & (~ (HOST_WIDE_INT) 0xffff0000)) == 0)));
+                     & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0))
+#if HOST_BITS_PER_WIDE_INT == 32
+         || (GET_CODE (op) == CONST_DOUBLE
+             && CONST_DOUBLE_HIGH (op) == 0
+             && ((CONST_DOUBLE_LOW (op)
+                  & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0))
+#endif
+      );
 }
 
 /* Return 1 if C is a constant that is not a logical operand (as
@@ -932,10 +997,39 @@ non_logical_cint_operand (op, mode)
      enum machine_mode mode;
 {
   return (GET_CODE (op) == CONST_INT
+#if HOST_BITS_PER_WIDE_INT != 32
+         && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
          && (INTVAL (op) & GET_MODE_MASK (mode) &
              (~ (HOST_WIDE_INT) 0xffff)) != 0
          && (INTVAL (op) & GET_MODE_MASK (mode) &
-             (~ (HOST_WIDE_INT) 0xffff0000)) != 0);
+             (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0);
+}
+
+/* Return 1 if C is an unsigned 32-bit constant that is not a
+   logical operand (as above).  */
+
+int
+non_logical_u_cint_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  return ((GET_CODE (op) == CONST_INT
+          && INTVAL (op) > 0
+#if HOST_BITS_PER_WIDE_INT != 32
+          && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+#endif
+          && (INTVAL (op) & GET_MODE_MASK (mode)
+              & (~ (HOST_WIDE_INT) 0xffff)) != 0
+          && (INTVAL (op) & GET_MODE_MASK (mode)
+              & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0)
+#if HOST_BITS_PER_WIDE_INT == 32
+         || (GET_CODE (op) == CONST_DOUBLE
+             && CONST_DOUBLE_HIGH (op) == 0
+             && (CONST_DOUBLE_LOW (op) & (~ (HOST_WIDE_INT) 0xffff)) != 0
+             && (CONST_DOUBLE_LOW (op)
+                 & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0));
+#endif
 }
 
 /* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
@@ -1055,7 +1149,7 @@ and64_operand (op, mode)
     register rtx op;
     enum machine_mode mode;
 {
-  if (fixed_regs[68])  /* CR0 not available, don't do andi./andis. */
+  if (fixed_regs[CR0_REGNO])   /* CR0 not available, don't do andi./andis. */
     return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
 
   return (logical_operand (op, mode) || mask64_operand (op, mode));
@@ -1069,7 +1163,7 @@ and_operand (op, mode)
     register rtx op;
     enum machine_mode mode;
 {
-  if (fixed_regs[68])  /* CR0 not available, don't do andi./andis. */
+  if (fixed_regs[CR0_REGNO])   /* CR0 not available, don't do andi./andis. */
     return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
 
   return (logical_operand (op, mode) || mask_operand (op, mode));
@@ -1182,10 +1276,8 @@ input_operand (op, mode)
   if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
     return 1;
 
-  /* Windows NT allows SYMBOL_REFs and LABEL_REFs against the TOC
-     directly in the instruction stream */
-  if (DEFAULT_ABI == ABI_NT
-      && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF))
+  /* A constant pool expression (relative to the TOC) is valid */
+  if (TOC_RELATIVE_EXPR_P (op))
     return 1;
 
   /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
@@ -1246,6 +1338,138 @@ small_data_operand (op, mode)
   return 0;
 #endif
 }
+\f
+static int 
+constant_pool_expr_1 (op, have_sym, have_toc) 
+    rtx op;
+    int *have_sym;
+    int *have_toc;
+{
+  switch (GET_CODE(op)) 
+    {
+    case SYMBOL_REF:
+       if (CONSTANT_POOL_ADDRESS_P (op))
+         {
+          if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op)))
+            {
+              *have_sym = 1;
+              return 1;
+            }
+          else
+            return 0;
+         }
+       else if (! strcmp (XSTR (op, 0), toc_label_name))
+         {
+           *have_toc = 1;
+           return 1;
+         }
+       else
+         return 0;
+    case PLUS:
+    case MINUS:
+       return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc) &&
+               constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc);
+    case CONST:
+       return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
+    case CONST_INT:
+       return 1;
+    default:
+       return 0;
+    }
+}
+
+int
+constant_pool_expr_p (op)
+    rtx op;
+{
+  int have_sym = 0;
+  int have_toc = 0;
+  return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
+}
+
+int
+toc_relative_expr_p (op)
+    rtx op;
+{
+    int have_sym = 0;
+    int have_toc = 0;
+    return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
+}
+
+/* Try machine-dependent ways of modifying an illegitimate address
+   to be legitimate.  If we find one, return the new, valid address.
+   This is used from only one place: `memory_address' in explow.c.
+
+   OLDX is the address as it was before break_out_memory_refs was called.
+   In some cases it is useful to look at this to decide what needs to be done.
+
+   MODE is passed so that this macro can use GO_IF_LEGITIMATE_ADDRESS.
+
+   It is always safe for this macro to do nothing.  It exists to recognize
+   opportunities to optimize the output.
+
+   On RS/6000, first check for the sum of a register with a constant
+   integer that is out of range.  If so, generate code to add the
+   constant with the low-order 16 bits masked to the register and force
+   this result into another register (this can be done with `cau').
+   Then generate an address of REG+(CONST&0xffff), allowing for the
+   possibility of bit 16 being a one.
+
+   Then check for the sum of a register and something not constant, try to
+   load the other things into a register and return the sum.  */
+rtx
+rs6000_legitimize_address (x, oldx, mode)
+     rtx x;
+     rtx oldx ATTRIBUTE_UNUSED;
+     enum machine_mode mode;
+{ 
+  if (GET_CODE (x) == PLUS 
+      && GET_CODE (XEXP (x, 0)) == REG
+      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
+    { 
+      HOST_WIDE_INT high_int, low_int;
+      rtx sum;
+      high_int = INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff);
+      low_int = INTVAL (XEXP (x, 1)) & 0xffff;
+      if (low_int & 0x8000)
+       high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
+      sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
+                                        GEN_INT (high_int)), 0);
+      return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
+    }
+  else if (GET_CODE (x) == PLUS 
+          && GET_CODE (XEXP (x, 0)) == REG
+          && GET_CODE (XEXP (x, 1)) != CONST_INT
+          && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode)
+          && (TARGET_POWERPC64 || mode != DImode)
+          && mode != TImode)
+    {
+      return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+                          force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
+    }
+  else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
+          && GET_CODE (x) != CONST_INT
+          && GET_CODE (x) != CONST_DOUBLE 
+          && CONSTANT_P (x)
+          && (TARGET_HARD_FLOAT || mode != DFmode)
+          && mode != DImode 
+          && mode != TImode)
+    {
+      rtx reg = gen_reg_rtx (Pmode);
+      emit_insn (gen_elf_high (reg, (x)));
+      return gen_rtx_LO_SUM (Pmode, reg, (x));
+    }
+  else if (TARGET_TOC 
+          && CONSTANT_POOL_EXPR_P (x)
+          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x)))
+    {
+      return create_TOC_reference (x);
+    }
+  else
+    return NULL_RTX;
+}
+
 
 \f
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
@@ -1263,7 +1487,6 @@ init_cumulative_args (cum, fntype, libname, incoming)
      int incoming;
 {
   static CUMULATIVE_ARGS zero_cumulative;
-  enum rs6000_abi abi = DEFAULT_ABI;
 
   *cum = zero_cumulative;
   cum->words = 0;
@@ -1285,14 +1508,8 @@ init_cumulative_args (cum, fntype, libname, incoming)
 
   cum->orig_nargs = cum->nargs_prototype;
 
-  /* Check for DLL import functions */
-  if (abi == ABI_NT
-      && fntype
-      && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype)))
-    cum->call_cookie = CALL_NT_DLLIMPORT;
-
-  /* Also check for longcall's */
-  else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
+  /* Check for longcall's */
+  if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
     cum->call_cookie = CALL_LONG;
 
   if (TARGET_DEBUG_ARG)
@@ -1305,9 +1522,6 @@ init_cumulative_args (cum, fntype, libname, incoming)
                   tree_code_name[ (int)TREE_CODE (ret_type) ]);
        }
 
-      if (cum->call_cookie & CALL_NT_DLLIMPORT)
-       fprintf (stderr, " dllimport,");
-
       if (cum->call_cookie & CALL_LONG)
        fprintf (stderr, " longcall,");
 
@@ -1325,48 +1539,40 @@ init_cumulative_args (cum, fntype, libname, incoming)
    For the AIX ABI structs are always stored left shifted in their
    argument slot.  */
 
-int
+enum direction
 function_arg_padding (mode, type)
      enum machine_mode mode;
      tree type;
 {
   if (type != 0 && AGGREGATE_TYPE_P (type))
-    return (int)upward;
+    return upward;
 
   /* This is the default definition.  */
   return (! BYTES_BIG_ENDIAN
-          ? (int)upward
+          ? upward
           : ((mode == BLKmode
               ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
                  && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
               : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
-             ? (int)downward : (int)upward));
+             ? downward : upward));
 }
 
 /* If defined, a C expression that gives the alignment boundary, in bits,
    of an argument with the specified mode and type.  If it is not defined, 
    PARM_BOUNDARY is used for all arguments.
    
-   Windows NT wants anything >= 8 bytes to be double word aligned.
-
    V.4 wants long longs to be double word aligned.  */
 
 int
 function_arg_boundary (mode, type)
      enum machine_mode mode;
-     tree type;
+     tree type ATTRIBUTE_UNUSED;
 {
   if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
       && (mode == DImode || mode == DFmode))
     return 64;
-
-  if (DEFAULT_ABI != ABI_NT || TARGET_64BIT)
+  else
     return PARM_BOUNDARY;
-
-  if (mode != BLKmode)
-    return (GET_MODE_SIZE (mode)) >= 8 ? 64 : 32;
-
-  return (int_size_in_bytes (type) >= 8) ? 64 : 32;
 }
 \f
 /* Update the data in CUM to advance over an argument
@@ -1660,7 +1866,6 @@ function_arg_pass_by_reference (cum, mode, type, named)
 
   return 0;
 }
-
 \f
 /* Perform any needed actions needed for a function that is receiving a
    variable number of arguments. 
@@ -1749,7 +1954,7 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
       && next_cum.fregno <= FP_ARG_V4_MAX_REG)
     {
       int fregno = next_cum.fregno;
-      rtx cr1 = gen_rtx_REG (CCmode, 69);
+      rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
       rtx lab = gen_label_rtx ();
       int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
 
@@ -1780,18 +1985,19 @@ tree
 rs6000_build_va_list ()
 {
   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
-  tree uchar_type_node;
 
-  /* Only SVR4 needs something special.  */
+  /* For AIX, prefer 'char *' because that's what the system
+     header files like.  */
   if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
-    return ptr_type_node;
+    return build_pointer_type (char_type_node);
 
   record = make_lang_type (RECORD_TYPE);
   type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
-  uchar_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
 
-  f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"), uchar_type_node);
-  f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"), uchar_type_node);
+  f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"), 
+                     unsigned_char_type_node);
+  f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"), 
+                     unsigned_char_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"),
@@ -1891,9 +2097,48 @@ rs6000_va_arg (valist, type)
   int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
   rtx lab_false, lab_over, addr_rtx, r;
 
-  /* Only SVR4 needs something special.  */
+  /* For AIX, the rule is that structures are passed left-aligned in
+     their stack slot.  However, GCC does not presently do this:
+     structures which are the same size as integer types are passed
+     right-aligned, as if they were in fact integers.  This only
+     matters for structures of size 1 or 2, or 4 when TARGET_64BIT.  */
   if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
-    return std_expand_builtin_va_arg (valist, type);
+    {
+      HOST_WIDE_INT align, rounded_size;
+      enum machine_mode mode;
+      tree addr_tree;
+
+      /* Compute the rounded size of the type.  */
+      align = PARM_BOUNDARY / BITS_PER_UNIT;
+      rounded_size = (((int_size_in_bytes (type) + align - 1) / align)
+                     * align);
+
+      addr_tree = valist;
+
+      mode = TYPE_MODE (type);
+      if (mode != BLKmode)
+       {
+         HOST_WIDE_INT adj;
+         adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
+         if (rounded_size > align)
+           adj = rounded_size;
+         
+         addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
+                            build_int_2 (rounded_size - adj, 0));
+       }
+
+      addr_rtx = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
+      addr_rtx = copy_to_reg (addr_rtx);
+      
+      /* Compute new value for AP.  */
+      t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+                build (PLUS_EXPR, TREE_TYPE (valist), valist,
+                       build_int_2 (rounded_size, 0)));
+      TREE_SIDE_EFFECTS (t) = 1;
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+      
+      return addr_rtx;
+    }
 
   f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
   f_fpr = TREE_CHAIN (f_gpr);
@@ -2431,6 +2676,215 @@ store_multiple_operation (op, mode)
 
   return 1;
 }
+
+/* Return 1 for an PARALLEL suitable for mtcrf. */
+
+int
+mtcrf_operation (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  int count = XVECLEN (op, 0);
+  int i;
+  int bitmap = 0;
+  rtx src_reg;
+
+  /* Perform a quick check so we don't blow up below.  */
+  if (count < 2
+      || GET_CODE (XVECEXP (op, 0, 0)) != USE
+      || GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) != CONST_INT
+      || GET_CODE (XVECEXP (op, 0, 1)) != SET
+      || GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) != UNSPEC
+      || XVECLEN (SET_SRC (XVECEXP (op, 0, 1)), 0) != 2)
+    return 0;
+  src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 1)), 0, 0);
+  
+  if (GET_CODE (src_reg) != REG
+      || GET_MODE (src_reg) != SImode
+      || ! INT_REGNO_P (REGNO (src_reg)))
+    return 0;
+
+  for (i = 1; i < count; i++)
+    {
+      rtx exp = XVECEXP (op, 0, i);
+      rtx unspec;
+      int maskval;
+      
+      if (GET_CODE (exp) != SET
+         || GET_CODE (SET_DEST (exp)) != REG
+         || GET_MODE (SET_DEST (exp)) != CCmode
+         || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
+       return 0;
+      unspec = SET_SRC (exp);
+      maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
+      bitmap |= maskval;
+      
+      if (GET_CODE (unspec) != UNSPEC
+         || XINT (unspec, 1) != 20
+         || XVECLEN (unspec, 0) != 2
+         || XVECEXP (unspec, 0, 0) != src_reg
+         || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
+         || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
+       return 0;
+    }
+  return INTVAL (XEXP (XVECEXP (op, 0, 0), 0)) == bitmap;
+}
+
+/* Return 1 for an PARALLEL suitable for lmw. */
+
+int
+lmw_operation (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  int count = XVECLEN (op, 0);
+  int dest_regno;
+  rtx src_addr;
+  int base_regno;
+  HOST_WIDE_INT offset;
+  int i;
+
+  /* Perform a quick check so we don't blow up below.  */
+  if (count <= 1
+      || GET_CODE (XVECEXP (op, 0, 0)) != SET
+      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
+      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
+    return 0;
+
+  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
+  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
+
+  if (dest_regno > 31
+      || count != 32 - dest_regno)
+    return 0;
+
+  if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr))
+    {
+      offset = 0;
+      base_regno = REGNO (src_addr);
+      if (base_regno == 0)
+       return 0;
+    }
+  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr))
+    {
+      offset = INTVAL (XEXP (src_addr, 1));
+      base_regno = REGNO (XEXP (src_addr, 0));
+    }
+  else
+    return 0;
+
+  for (i = 0; i < count; i++)
+    {
+      rtx elt = XVECEXP (op, 0, i);
+      rtx newaddr;
+      rtx addr_reg;
+      HOST_WIDE_INT newoffset;
+
+      if (GET_CODE (elt) != SET
+         || GET_CODE (SET_DEST (elt)) != REG
+         || GET_MODE (SET_DEST (elt)) != SImode
+         || REGNO (SET_DEST (elt)) != dest_regno + i
+         || GET_CODE (SET_SRC (elt)) != MEM
+         || GET_MODE (SET_SRC (elt)) != SImode)
+       return 0;
+      newaddr = XEXP (SET_SRC (elt), 0);
+      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
+       {
+         newoffset = 0;
+         addr_reg = newaddr;
+       }
+      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
+       {
+         addr_reg = XEXP (newaddr, 0);
+         newoffset = INTVAL (XEXP (newaddr, 1));
+       }
+      else
+       return 0;
+      if (REGNO (addr_reg) != base_regno
+         || newoffset != offset + 4 * i)
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Return 1 for an PARALLEL suitable for stmw. */
+
+int
+stmw_operation (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  int count = XVECLEN (op, 0);
+  int src_regno;
+  rtx dest_addr;
+  int base_regno;
+  HOST_WIDE_INT offset;
+  int i;
+
+  /* Perform a quick check so we don't blow up below.  */
+  if (count <= 1
+      || GET_CODE (XVECEXP (op, 0, 0)) != SET
+      || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
+      || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
+    return 0;
+
+  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
+  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
+
+  if (src_regno > 31
+      || count != 32 - src_regno)
+    return 0;
+
+  if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr))
+    {
+      offset = 0;
+      base_regno = REGNO (dest_addr);
+      if (base_regno == 0)
+       return 0;
+    }
+  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr))
+    {
+      offset = INTVAL (XEXP (dest_addr, 1));
+      base_regno = REGNO (XEXP (dest_addr, 0));
+    }
+  else
+    return 0;
+
+  for (i = 0; i < count; i++)
+    {
+      rtx elt = XVECEXP (op, 0, i);
+      rtx newaddr;
+      rtx addr_reg;
+      HOST_WIDE_INT newoffset;
+
+      if (GET_CODE (elt) != SET
+         || GET_CODE (SET_SRC (elt)) != REG
+         || GET_MODE (SET_SRC (elt)) != SImode
+         || REGNO (SET_SRC (elt)) != src_regno + i
+         || GET_CODE (SET_DEST (elt)) != MEM
+         || GET_MODE (SET_DEST (elt)) != SImode)
+       return 0;
+      newaddr = XEXP (SET_DEST (elt), 0);
+      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
+       {
+         newoffset = 0;
+         addr_reg = newaddr;
+       }
+      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
+       {
+         addr_reg = XEXP (newaddr, 0);
+         newoffset = INTVAL (XEXP (newaddr, 1));
+       }
+      else
+       return 0;
+      if (REGNO (addr_reg) != base_regno
+         || newoffset != offset + 4 * i)
+       return 0;
+    }
+
+  return 1;
+}
 \f
 /* Return 1 if OP is a comparison operation that is valid for a branch insn.
    We only check the opcode against the mode of the CC value here.  */
@@ -2691,13 +3145,20 @@ ccr_bit (op, scc_p)
   enum machine_mode cc_mode;
   int cc_regnum;
   int base_bit;
+  rtx reg;
 
   if (GET_RTX_CLASS (code) != '<')
     return -1;
 
-  cc_mode = GET_MODE (XEXP (op, 0));
-  cc_regnum = REGNO (XEXP (op, 0));
-  base_bit = 4 * (cc_regnum - 68);
+  reg = XEXP (op, 0);
+
+  if (GET_CODE (reg) != REG
+      || ! CR_REGNO_P (REGNO (reg)))
+    abort ();
+
+  cc_mode = GET_MODE (reg);
+  cc_regnum = REGNO (reg);
+  base_bit = 4 * (cc_regnum - CR0_REGNO);
 
   /* In CCEQmode cases we have made sure that the result is always in the
      third bit of the CR field.  */
@@ -2746,39 +3207,14 @@ rs6000_got_register (value)
 
   return pic_offset_table_rtx;
 }
-
-/* Search for any occurrence of the GOT_TOC register marker that should
-   have been eliminated, but may have crept back in.
-
-   This function could completely go away now (June 1999), but we leave it 
-   in for a while until all the possible issues with the new -fpic handling 
-   are resolved. */
-
-void
-rs6000_reorg (insn)
-     rtx insn;
-{
-  if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
-    {
-      rtx got_reg = gen_rtx_REG (Pmode, 2);
-      for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn))
-       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
-           && reg_mentioned_p (got_reg, PATTERN (insn)))
-         fatal_insn ("GOT/TOC register marker not removed:", PATTERN (insn));
-    }
-}
-
 \f
 /* Define the structure for the machine field in struct function.  */
 struct machine_function
 {
   int sysv_varargs_p;
-  int save_toc_p;
-  int fpmem_size;
-  int fpmem_offset;
 };
 
-/* Functions to save and restore rs6000_fpmem_size.
+/* Functions to save and restore sysv_varargs_p.
    These will be called, via pointer variables,
    from push_function_context and pop_function_context.  */
 
@@ -2791,8 +3227,6 @@ rs6000_save_machine_status (p)
 
   p->machine = machine;
   machine->sysv_varargs_p = rs6000_sysv_varargs_p;
-  machine->fpmem_size     = rs6000_fpmem_size;
-  machine->fpmem_offset   = rs6000_fpmem_offset;
 }
 
 void
@@ -2802,8 +3236,6 @@ rs6000_restore_machine_status (p)
   struct machine_function *machine = p->machine;
 
   rs6000_sysv_varargs_p = machine->sysv_varargs_p;
-  rs6000_fpmem_size     = machine->fpmem_size;
-  rs6000_fpmem_offset   = machine->fpmem_offset;
 
   free (machine);
   p->machine = (struct machine_function *)0;
@@ -2814,10 +3246,8 @@ rs6000_restore_machine_status (p)
 void
 rs6000_init_expanders ()
 {
-  /* Reset varargs and save TOC indicator */
+  /* Reset varargs */
   rs6000_sysv_varargs_p = 0;
-  rs6000_fpmem_size = 0;
-  rs6000_fpmem_offset = 0;
 
   /* Arrange to save and restore machine status around nested functions.  */
   save_machine_status = rs6000_save_machine_status;
@@ -2839,7 +3269,7 @@ void
 print_operand (file, x, code)
     FILE *file;
     rtx x;
-    char code;
+    int code;
 {
   int i;
   HOST_WIDE_INT val;
@@ -2860,11 +3290,6 @@ print_operand (file, x, code)
       asm_fprintf (file, RS6000_CALL_GLUE);
       return;
 
-    case '*':
-      /* Write the register number of the TOC register.  */
-      fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2 /* PIC_OFFSET_TABLE_REGNUM? */ ], file);
-      return;
-
     case '$':
       /* Write out either a '.' or '$' for the current location, depending
         on whether this is Solaris or not.  */
@@ -2902,7 +3327,7 @@ print_operand (file, x, code)
       if ((GET_CODE (x) == LE || GET_CODE (x) == GE)
          && GET_MODE (XEXP (x, 0)) == CCFPmode)
        {
-         int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
+         int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
 
          fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
                   base_bit + 2, base_bit + (GET_CODE (x) == GE));
@@ -2916,7 +3341,7 @@ print_operand (file, x, code)
       if (GET_CODE (x) == LE || GET_CODE (x) == GE
          || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
        {
-         int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
+         int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
 
          fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
                   base_bit + 2,
@@ -2925,7 +3350,7 @@ print_operand (file, x, code)
 
       else if (GET_CODE (x) == NE)
        {
-         int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
+         int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
 
          fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
                   base_bit + 2, base_bit + 2);
@@ -2937,7 +3362,7 @@ print_operand (file, x, code)
       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%E value");
 
-      fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3);
+      fprintf(file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 3);
       return;
 
     case 'f':
@@ -2946,7 +3371,7 @@ print_operand (file, x, code)
       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%f value");
       else
-       fprintf (file, "%d", 4 * (REGNO (x) - 68));
+       fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
       return;
 
     case 'F':
@@ -2955,7 +3380,7 @@ print_operand (file, x, code)
       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%F value");
       else
-       fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68));
+       fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
       return;
 
     case 'G':
@@ -3022,6 +3447,27 @@ print_operand (file, x, code)
       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
       return;
 
+    case 'l':
+      /* X must be a symbolic constant on ELF.  Write an
+        expression suitable for an 'addi' that adds in the low 16
+        bits of the MEM.  */
+      if (GET_CODE (x) != CONST)
+       {
+         print_operand_address (file, x);
+         fputs ("@l", file);
+       }
+      else
+       {
+         if (GET_CODE (XEXP (x, 0)) != PLUS
+             || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
+                 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
+             || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
+           output_operand_lossage ("invalid %%l value");
+         print_operand_address (file, XEXP (XEXP (x, 0), 0));
+         fputs ("@l", file);
+         print_operand (file, XEXP (XEXP (x, 0), 1), 0);
+       }
+
     case 'L':
       /* Write second word of DImode or DFmode reference.  Works on register
         or non-indexed memory only.  */
@@ -3054,15 +3500,15 @@ print_operand (file, x, code)
       /* If the high bit is set and the low bit is not, the value is zero.
         If the high bit is zero, the value is the first 1 bit we find from
         the left.  */
-      if ((val & 0x80000000) && ((val & 1) == 0))
+      if ((val & 0x80000000u) && ((val & 1) == 0))
        {
          putc ('0', file);
          return;
        }
-      else if ((val & 0x80000000) == 0)
+      else if ((val & 0x80000000u) == 0)
        {
          for (i = 1; i < 32; i++)
-           if ((val <<= 1) & 0x80000000)
+           if ((val <<= 1) & 0x80000000u)
              break;
          fprintf (file, "%d", i);
          return;
@@ -3089,7 +3535,7 @@ print_operand (file, x, code)
       /* If the low bit is set and the high bit is not, the value is 31.
         If the low bit is zero, the value is the first 1 bit we find from
         the right.  */
-      if ((val & 1) && ((val & 0x80000000) == 0))
+      if ((val & 1) && ((val & 0x80000000u) == 0))
        {
          fputs ("31", file);
          return;
@@ -3109,7 +3555,7 @@ print_operand (file, x, code)
       /* Otherwise, look for the first 0 bit from the left.  The result is its
         number minus 1. We know the high-order bit is one.  */
       for (i = 0; i < 32; i++)
-       if (((val <<= 1) & 0x80000000) == 0)
+       if (((val <<= 1) & 0x80000000u) == 0)
          break;
 
       fprintf (file, "%d", i);
@@ -3155,7 +3601,7 @@ print_operand (file, x, code)
       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        output_operand_lossage ("invalid %%R value");
       else
-       fprintf (file, "%d", 128 >> (REGNO (x) - 68));
+       fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
       return;
 
     case 's':
@@ -3399,13 +3845,13 @@ print_operand (file, x, code)
            case ABI_AIX_NODESC:
            case ABI_SOLARIS:
              break;
-
-           case ABI_NT:
-             fputs ("..", file);
-             break;
            }
        }
+#if TARGET_AIX
       RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
+#else
+      assemble_name (file, XSTR (x, 0));
+#endif
       return;
 
     case 'Z':
@@ -3459,19 +3905,15 @@ print_operand_address (file, x)
 {
   if (GET_CODE (x) == REG)
     fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
-  else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST || GET_CODE (x) == LABEL_REF)
+  else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
+          || GET_CODE (x) == LABEL_REF)
     {
       output_addr_const (file, x);
       if (small_data_operand (x, GET_MODE (x)))
        fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
                 reg_names[SMALL_DATA_REG]);
-
-#ifdef TARGET_NO_TOC
-      else if (TARGET_NO_TOC)
-       ;
-#endif
-      else
-       fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 /* PIC_OFFSET_TABLE_REGNUM? */ ]);
+      else if (TARGET_TOC)
+       abort();
     }
   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
     {
@@ -3495,6 +3937,28 @@ print_operand_address (file, x)
       fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
     }
 #endif
+  else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
+    {
+      if (TARGET_AIX)
+       {
+         rtx contains_minus = XEXP (x, 1); 
+         rtx minus;
+         
+         /* Find the (minus (sym) (toc)) buried in X, and temporarily
+            turn it into (sym) for output_addr_const. */
+         while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
+           contains_minus = XEXP (contains_minus, 0);
+
+         minus = XEXP (contains_minus, 0); 
+         XEXP (contains_minus, 0) = XEXP (minus, 0);
+         output_addr_const (file, XEXP (x, 1));          
+         XEXP (contains_minus, 0) = minus;
+       }
+      else
+       output_addr_const (file, XEXP (x, 1));
+
+      fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
+    }
   else
     abort ();
 }
@@ -3577,27 +4041,6 @@ first_fp_reg_to_save ()
 
   return first_reg;
 }
-
-/* Return non-zero if this function makes calls.  */
-
-int
-rs6000_makes_calls ()
-{
-  rtx insn;
-
-  /* If we are profiling, we will be making a call to __mcount.
-     Under the System V ABI's, we store the LR directly, so
-     we don't need to do it here.  */
-  if (DEFAULT_ABI == ABI_AIX && profile_flag)
-    return 1;
-
-  for (insn = get_insns (); insn; insn = next_insn (insn))
-    if (GET_CODE (insn) == CALL_INSN)
-      return 1;
-
-  return 0;
-}
-
 \f
 /* Calculate the stack information for the current function.  This is
    complicated by having two separate calling sequences, the AIX calling
@@ -3671,53 +4114,6 @@ rs6000_makes_calls ()
    -mno-eabi libraries can be used with -meabi programs.)
 
 
-   A PowerPC Windows/NT frame looks like:
-
-       SP----> +---------------------------------------+
-               | back chain to caller                  | 0
-               +---------------------------------------+
-               | reserved                              | 4
-               +---------------------------------------+
-               | reserved                              | 8
-               +---------------------------------------+
-               | reserved                              | 12
-               +---------------------------------------+
-               | reserved                              | 16
-               +---------------------------------------+
-               | reserved                              | 20
-               +---------------------------------------+
-               | Parameter save area (P)               | 24
-               +---------------------------------------+
-               | Alloca space (A)                      | 24+P
-               +---------------------------------------+     
-               | Local variable space (L)              | 24+P+A
-               +---------------------------------------+     
-               | Float/int conversion temporary (X)    | 24+P+A+L
-               +---------------------------------------+
-               | Save area for FP registers (F)        | 24+P+A+L+X
-               +---------------------------------------+     
-               | Possible alignment area (Y)           | 24+P+A+L+X+F
-               +---------------------------------------+     
-               | Save area for GP registers (G)        | 24+P+A+L+X+F+Y
-               +---------------------------------------+     
-               | Save area for CR (C)                  | 24+P+A+L+X+F+Y+G
-               +---------------------------------------+     
-               | Save area for TOC (T)                 | 24+P+A+L+X+F+Y+G+C
-               +---------------------------------------+     
-               | Save area for LR (R)                  | 24+P+A+L+X+F+Y+G+C+T
-               +---------------------------------------+
-       old SP->| back chain to caller's caller         |
-               +---------------------------------------+
-
-   For NT, there is no specific order to save the registers, but in
-   order to support __builtin_return_address, the save area for the
-   link register needs to be in a known place, so we use -4 off of the
-   old SP.  To support calls through pointers, we also allocate a
-   fixed slot to store the TOC, -8 off the old SP.
-
-   The required alignment for NT is 16 bytes.
-
-
    The EABI configuration defaults to the V.4 layout, unless
    -mcall-aix is used, in which case the AIX layout is used.  However,
    the stack alignment requirements may differ.  If -mno-eabi is not
@@ -3734,7 +4130,7 @@ rs6000_stack_info ()
 {
   static rs6000_stack_t info, zero_info;
   rs6000_stack_t *info_ptr = &info;
-  int reg_size = TARGET_32BIT ? 4 : 8;
+  int reg_size = TARGET_POWERPC64 ? 8 : 4;
   enum rs6000_abi abi;
   int total_raw_size;
 
@@ -3759,54 +4155,10 @@ rs6000_stack_info ()
   info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
 
   /* Does this function call anything? */
-  info_ptr->calls_p = rs6000_makes_calls ();
-
-  /* Allocate space to save the toc. */
-  if (abi == ABI_NT && info_ptr->calls_p)
-    {
-      info_ptr->toc_save_p = 1;
-      info_ptr->toc_size = reg_size;
-    }
-
-  /* Does this machine need the float/int conversion area? */
-  info_ptr->fpmem_p = regs_ever_live[FPMEM_REGNUM];
-
-  /* If this is main and we need to call a function to set things up,
-     save main's arguments around the call.  */
-#ifdef TARGET_EABI
-  if (TARGET_EABI)
-#endif
-    {
-      if (0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
-                      "main")
-         && DECL_CONTEXT (current_function_decl) == NULL_TREE)
-       {
-         info_ptr->main_p = 1;
-
-#ifdef NAME__MAIN
-         info_ptr->calls_p = 1;
-
-         if (DECL_ARGUMENTS (current_function_decl))
-           {
-             int i;
-             tree arg;
-
-             info_ptr->main_save_p = 1;
-             info_ptr->main_size = 0;
-
-             for ((i = 0), (arg = DECL_ARGUMENTS (current_function_decl));
-                  arg != NULL_TREE && i < 8;
-                  (arg = TREE_CHAIN (arg)), i++)
-               {
-                 info_ptr->main_size += reg_size;
-               }
-           }
-#endif
-       }
-    }
+  info_ptr->calls_p = ! current_function_is_leaf;
 
   /* Determine if we need to save the link register */
-  if (regs_ever_live[65]
+  if (regs_ever_live[LINK_REGISTER_REGNUM]
       || (DEFAULT_ABI == ABI_AIX && profile_flag)
 #ifdef TARGET_RELOCATABLE
       || (TARGET_RELOCATABLE && (get_pool_size () != 0))
@@ -3818,16 +4170,16 @@ rs6000_stack_info ()
       || info_ptr->calls_p)
     {
       info_ptr->lr_save_p = 1;
-      regs_ever_live[65] = 1;
-      if (abi == ABI_NT)
-       info_ptr->lr_size = reg_size;
+      regs_ever_live[LINK_REGISTER_REGNUM] = 1;
     }
 
-  /* Determine if we need to save the condition code registers */
-  if (regs_ever_live[70] || regs_ever_live[71] || regs_ever_live[72])
+  /* Determine if we need to save the condition code registers.  */
+  if (regs_ever_live[CR2_REGNO] 
+      || regs_ever_live[CR3_REGNO]
+      || regs_ever_live[CR4_REGNO])
     {
       info_ptr->cr_save_p = 1;
-      if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS)
+      if (abi == ABI_V4 || abi == ABI_SOLARIS)
        info_ptr->cr_size = reg_size;
     }
 
@@ -3837,13 +4189,11 @@ rs6000_stack_info ()
   info_ptr->varargs_size = RS6000_VARARGS_AREA;
   info_ptr->vars_size    = RS6000_ALIGN (get_frame_size (), 8);
   info_ptr->parm_size    = RS6000_ALIGN (current_function_outgoing_args_size, 8);
-  info_ptr->fpmem_size  = (info_ptr->fpmem_p) ? 8 : 0;
   info_ptr->save_size    = RS6000_ALIGN (info_ptr->fp_size
                                  + info_ptr->gp_size
                                  + info_ptr->cr_size
                                  + info_ptr->lr_size
-                                 + info_ptr->toc_size
-                                 + info_ptr->main_size, 8);
+                                 + info_ptr->toc_size, 8);
 
   /* Calculate the offsets */
   switch (abi)
@@ -3856,7 +4206,6 @@ rs6000_stack_info ()
     case ABI_AIX_NODESC:
       info_ptr->fp_save_offset   = - info_ptr->fp_size;
       info_ptr->gp_save_offset   = info_ptr->fp_save_offset - info_ptr->gp_size;
-      info_ptr->main_save_offset = info_ptr->gp_save_offset - info_ptr->main_size;
       info_ptr->cr_save_offset   = reg_size; /* first word when 64-bit.  */
       info_ptr->lr_save_offset   = 2*reg_size;
       break;
@@ -3867,31 +4216,12 @@ rs6000_stack_info ()
       info_ptr->gp_save_offset   = info_ptr->fp_save_offset - info_ptr->gp_size;
       info_ptr->cr_save_offset   = info_ptr->gp_save_offset - info_ptr->cr_size;
       info_ptr->toc_save_offset  = info_ptr->cr_save_offset - info_ptr->toc_size;
-      info_ptr->main_save_offset = info_ptr->toc_save_offset - info_ptr->main_size;
       info_ptr->lr_save_offset   = reg_size;
       break;
-
-    case ABI_NT:
-      info_ptr->lr_save_offset    = -reg_size;
-      info_ptr->toc_save_offset   = info_ptr->lr_save_offset - info_ptr->lr_size;
-      info_ptr->cr_save_offset    = info_ptr->toc_save_offset - info_ptr->toc_size;
-      info_ptr->gp_save_offset    = info_ptr->cr_save_offset - info_ptr->cr_size - info_ptr->gp_size + reg_size;
-      info_ptr->fp_save_offset    = info_ptr->gp_save_offset - info_ptr->fp_size;
-      if (info_ptr->fp_size && ((- info_ptr->fp_save_offset) % 8) != 0)
-       info_ptr->fp_save_offset -= reg_size;
-
-      info_ptr->main_save_offset = info_ptr->fp_save_offset - info_ptr->main_size;
-      break;
     }
 
-  /* Ensure that fpmem_offset will be aligned to an 8-byte boundary. */
-  if (info_ptr->fpmem_p
-      && (info_ptr->main_save_offset - info_ptr->fpmem_size) % 8)
-    info_ptr->fpmem_size += reg_size;
-
   total_raw_size        = (info_ptr->vars_size
                            + info_ptr->parm_size
-                           + info_ptr->fpmem_size
                            + info_ptr->save_size
                            + info_ptr->varargs_size
                            + info_ptr->fixed_size);
@@ -3902,7 +4232,7 @@ rs6000_stack_info ()
 
      For AIX we need to push the stack if a frame pointer is needed (because
      the stack might be dynamically adjusted), if we are debugging, if we
-     make calls, or if the sum of fp_save, gp_save, fpmem, and local variables
+     make calls, or if the sum of fp_save, gp_save, and local variables
      are more than the space needed to save all non-volatile registers:
      32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8 + 18*8 = 288 (GPR13 reserved).
 
@@ -3912,10 +4242,9 @@ rs6000_stack_info ()
   if (info_ptr->calls_p)
     info_ptr->push_p = 1;
 
-  else if (abi == ABI_V4 || abi == ABI_NT || abi == ABI_SOLARIS)
+  else if (abi == ABI_V4 || abi == ABI_SOLARIS)
     info_ptr->push_p = (total_raw_size > info_ptr->fixed_size
-                       || (abi == ABI_NT ? info_ptr->lr_save_p
-                           : info_ptr->calls_p));
+                       || info_ptr->calls_p);
 
   else
     info_ptr->push_p = (frame_pointer_needed
@@ -3923,17 +4252,6 @@ rs6000_stack_info ()
                        || ((total_raw_size - info_ptr->fixed_size)
                            > (TARGET_32BIT ? 220 : 288)));
 
-  if (info_ptr->fpmem_p)
-    {
-      info_ptr->fpmem_offset = info_ptr->main_save_offset - info_ptr->fpmem_size;
-      rs6000_fpmem_size   = info_ptr->fpmem_size;
-      rs6000_fpmem_offset = (info_ptr->push_p
-                            ? info_ptr->total_size + info_ptr->fpmem_offset
-                            : info_ptr->fpmem_offset);
-    }
-  else
-    info_ptr->fpmem_offset = 0;  
-
   /* Zero offsets if we're not saving those registers */
   if (info_ptr->fp_size == 0)
     info_ptr->fp_save_offset = 0;
@@ -3950,9 +4268,6 @@ rs6000_stack_info ()
   if (! info_ptr->toc_save_p)
     info_ptr->toc_save_offset = 0;
 
-  if (! info_ptr->main_save_p)
-    info_ptr->main_save_offset = 0;
-
   return info_ptr;
 }
 
@@ -3978,7 +4293,6 @@ debug_stack_info (info)
     case ABI_AIX_NODESC: abi_string = "AIX";           break;
     case ABI_V4:        abi_string = "V.4";            break;
     case ABI_SOLARIS:   abi_string = "Solaris";        break;
-    case ABI_NT:        abi_string = "NT";             break;
     }
 
   fprintf (stderr, "\tABI                 = %5s\n", abi_string);
@@ -4004,15 +4318,6 @@ debug_stack_info (info)
   if (info->calls_p)
     fprintf (stderr, "\tcalls_p             = %5d\n", info->calls_p);
 
-  if (info->main_p)
-    fprintf (stderr, "\tmain_p              = %5d\n", info->main_p);
-
-  if (info->main_save_p)
-    fprintf (stderr, "\tmain_save_p         = %5d\n", info->main_save_p);
-
-  if (info->fpmem_p)
-    fprintf (stderr, "\tfpmem_p             = %5d\n", info->fpmem_p);
-
   if (info->gp_save_offset)
     fprintf (stderr, "\tgp_save_offset      = %5d\n", info->gp_save_offset);
 
@@ -4031,12 +4336,6 @@ debug_stack_info (info)
   if (info->varargs_save_offset)
     fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
 
-  if (info->main_save_offset)
-    fprintf (stderr, "\tmain_save_offset    = %5d\n", info->main_save_offset);
-
-  if (info->fpmem_offset)
-    fprintf (stderr, "\tfpmem_offset        = %5d\n", info->fpmem_offset);
-
   if (info->total_size)
     fprintf (stderr, "\ttotal_size          = %5d\n", info->total_size);
 
@@ -4049,9 +4348,6 @@ debug_stack_info (info)
   if (info->parm_size)
     fprintf (stderr, "\tparm_size           = %5d\n", info->parm_size);
 
-  if (info->fpmem_size)
-    fprintf (stderr, "\tfpmem_size          = %5d\n", info->fpmem_size);
-
   if (info->fixed_size)
     fprintf (stderr, "\tfixed_size          = %5d\n", info->fixed_size);
 
@@ -4070,9 +4366,6 @@ debug_stack_info (info)
  if (info->toc_size)
     fprintf (stderr, "\ttoc_size            = %5d\n", info->toc_size);
 
- if (info->main_size)
-    fprintf (stderr, "\tmain_size           = %5d\n", info->main_size);
-
   if (info->save_size)
     fprintf (stderr, "\tsave_size           = %5d\n", info->save_size);
 
@@ -4082,104 +4375,303 @@ debug_stack_info (info)
   fprintf (stderr, "\n");
 }
 \f
-/* Write out an instruction to load the TOC_TABLE address into register 30.
+/* Emit instructions needed to load the TOC register.
    This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
-   a constant pool.  */
+   a constant pool; or for SVR4 -fpic.  */
 
 void
-rs6000_output_load_toc_table (file, reg)
-     FILE *file;
-     int reg;
+rs6000_emit_load_toc_table (fromprolog)
+     int fromprolog;
 {
-  char buf[256];
+  rtx dest;
+  dest = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
 
-#ifdef USING_SVR4_H
-  if (TARGET_RELOCATABLE)
+  if (TARGET_ELF)
     {
-      ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
-      fprintf (file, "\tbl ");
-      assemble_name (file, buf);
-      fprintf (file, "\n");
-
-      /* possibly create the toc section */
-      if (! toc_initialized)
+      if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) 
+         && flag_pic == 1)
        {
-         toc_section ();
-         function_section (current_function_decl);
+         rtx temp = (fromprolog 
+                     ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+                     : gen_reg_rtx (Pmode));
+         if (TARGET_32BIT)
+           emit_insn (gen_load_toc_v4_pic_si (temp));
+         else
+           emit_insn (gen_load_toc_v4_pic_di (temp));
+         emit_move_insn (dest, temp);
        }
+      else if (flag_pic == 2)
+        {
+         char buf[30];
+         rtx tempLR = (fromprolog 
+                       ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+                       : gen_reg_rtx (Pmode));
+         rtx temp0 = (fromprolog
+                       ? gen_rtx_REG (Pmode, 0)
+                       : gen_reg_rtx (Pmode));
+         rtx symF;
+
+         /* possibly create the toc section */
+         if (! toc_initialized)
+           {
+             toc_section ();
+             function_section (current_function_decl);
+           }
+  
+         if (fromprolog)
+           {
+             rtx symL;
+         
+             ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+             symF = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
 
-      /* If not first call in this function, we need to put the
-        different between .LCTOC1 and the address we get to right
-        after the bl.  It will mess up disassembling the instructions
-        but that can't be helped.  We will later need to bias the
-        address before loading.  */
-      if (rs6000_pic_func_labelno != rs6000_pic_labelno)
-       {
-         const char *init_ptr = TARGET_32BIT ? ".long" : ".quad";
-         const char *buf_ptr;
+             ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
+             symL = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
 
-         ASM_OUTPUT_INTERNAL_LABEL (file, "LCL", rs6000_pic_labelno);
+             emit_insn (gen_load_toc_v4_PIC_1 (tempLR, symF));
+             emit_move_insn (dest, tempLR);
+             emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
+           }
+         else
+           {
+             rtx tocsym;
+             static int reload_toc_labelno = 0;
+
+             tocsym = gen_rtx_SYMBOL_REF (Pmode, 
+                     ggc_alloc_string (toc_label_name, -1));
 
+             ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
+             symF = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
+
+             emit_insn (gen_load_toc_v4_PIC_1b (tempLR, symF, tocsym));
+             emit_move_insn (dest, tempLR);
+             emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
+           }
+         emit_insn (gen_addsi3 (dest, temp0, dest));
+       }
+      else if (flag_pic == 0 && TARGET_MINIMAL_TOC)
+        {
+         /* This is for AIX code running in non-PIC ELF.  */
+         char buf[30];
+         rtx realsym;
          ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
-         STRIP_NAME_ENCODING (buf_ptr, buf);
-         fprintf (file, "\t%s %s-", init_ptr, buf_ptr);
+         realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
+         
+         emit_insn (gen_elf_high (dest, realsym));
+         emit_insn (gen_elf_low (dest, dest, realsym));
+       }
+      else
+        abort();
+    }
+  else
+    {
+      if (TARGET_32BIT)
+        emit_insn (gen_load_toc_aix_si (dest));
+      else
+        emit_insn (gen_load_toc_aix_di (dest));
+    }
+}
+
+int   
+get_TOC_alias_set ()
+{
+    static int set = -1;
+    if (set == -1)
+      set = new_alias_set ();
+    return set;
+}   
+
+/* This retuns nonzero if the current function uses the TOC.  This is
+   determined by the presence of (unspec ... 7), which is generated by
+   the various load_toc_* patterns.  */
+int
+uses_TOC () 
+{
+    rtx insn;
 
-         ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
-         fprintf (file, "%s\n", buf_ptr);
+    for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+       {
+         rtx pat = PATTERN (insn);
+         int i;
+
+         if (GET_CODE(pat) == PARALLEL) 
+           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC 
+                && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
+                 return 1;
        }
+    return 0;
+}
 
-      ASM_OUTPUT_INTERNAL_LABEL (file, "LCF", rs6000_pic_labelno);
-      fprintf (file, "\tmflr %s\n", reg_names[reg]);
+rtx
+create_TOC_reference(symbol) 
+    rtx symbol;
+{
+    return gen_rtx_PLUS (Pmode, 
+            gen_rtx_REG (Pmode, TOC_REGISTER),
+              gen_rtx_CONST (Pmode, 
+                gen_rtx_MINUS (Pmode, symbol, 
+                  gen_rtx_SYMBOL_REF (Pmode,
+                    ggc_alloc_string (toc_label_name, -1)))));
+}
 
-      if (rs6000_pic_func_labelno != rs6000_pic_labelno)
-         asm_fprintf(file, "\t{cal|la} %s,%d(%s)\n", reg_names[reg],
-                     (TARGET_32BIT ? 4 : 8), reg_names[reg]);
+#if TARGET_AIX
+/* __throw will restore its own return address to be the same as the
+   return address of the function that the throw is being made to.
+   This is unfortunate, because we want to check the original
+   return address to see if we need to restore the TOC.
+   So we have to squirrel it away here.  
+   This is used only in compiling __throw and __rethrow. 
 
-      asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s,(" : "\tld %s,(",
-                  reg_names[0]);
-      ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
-      assemble_name (file, buf);
-      putc ('-', file);
-      ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
-      assemble_name (file, buf);
-      fprintf (file, ")(%s)\n", reg_names[reg]);
-      asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
-                  reg_names[reg], reg_names[0], reg_names[reg]);
-      rs6000_pic_labelno++;
-    }
-  else if (! TARGET_64BIT)
-    {
-      ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
-      asm_fprintf (file, "\t{liu|lis} %s,", reg_names[reg]);
-      assemble_name (file, buf);
-      fputs ("@ha\n", file);
-      asm_fprintf (file, "\t{cal|la} %s,", reg_names[reg]);
-      assemble_name (file, buf);
-      asm_fprintf (file, "@l(%s)\n", reg_names[reg]);
-    }
-  else
-    abort ();
+   Most of this code should be removed by CSE.  */
+static rtx insn_after_throw;
 
-#else  /* !USING_SVR4_H */
-  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0);
-  asm_fprintf (file, TARGET_32BIT ? "\t{l|lwz} %s," : "\tld %s,",
-              reg_names[reg]);
-  assemble_name (file, buf);
-  asm_fprintf (file, "(%s)\n", reg_names[2]);
-#endif /* USING_SVR4_H */
+/* This does the saving... */
+void
+rs6000_aix_emit_builtin_unwind_init ()
+{
+  rtx mem;
+  rtx stack_top = gen_reg_rtx (Pmode);
+  rtx opcode_addr = gen_reg_rtx (Pmode);
+
+  insn_after_throw = gen_reg_rtx (SImode);
+
+  mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
+  emit_move_insn (stack_top, mem);
+
+  mem = gen_rtx_MEM (Pmode, 
+                    gen_rtx_PLUS (Pmode, stack_top, 
+                                  GEN_INT (2 * GET_MODE_SIZE (Pmode))));
+  emit_move_insn (opcode_addr, mem);
+  emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
 }
 
+/* Emit insns to _restore_ the TOC register, at runtime (specifically in _eh.o).
+   Only used on AIX.
+
+   The idea is that on AIX, function calls look like this:
+       bl  somefunction-trampoline
+       lwz r2,20(sp)
+
+    and later,
+       somefunction-trampoline:
+       stw r2,20(sp)
+        ... load function address in the count register ...
+       bctr
+   or like this, if the linker determines that this is not a cross-module call
+   and so the TOC need not be restored:
+       bl  somefunction
+       nop
+   or like this, if the compiler could determine that this is not a
+   cross-module call:
+       bl  somefunction
+   now, the tricky bit here is that register 2 is saved and restored
+   by the _linker_, so we can't readily generate debugging information
+   for it.  So we need to go back up the call chain looking at the
+   insns at return addresses to see which calls saved the TOC register
+   and so see where it gets restored from.
+
+   Oh, and all this gets done in RTL inside the eh_epilogue pattern,
+   just before the actual epilogue.
+
+   On the bright side, this incurs no space or time overhead unless an
+   exception is thrown, except for the extra code in libgcc.a.  
+
+   The parameter STACKSIZE is a register containing (at runtime)
+   the amount to be popped off the stack in addition to the stack frame
+   of this routine (which will be __throw or __rethrow, and so is
+   guaranteed to have a stack frame).  */
+void
+rs6000_emit_eh_toc_restore (stacksize)
+     rtx stacksize;
+{
+  rtx top_of_stack;
+  rtx bottom_of_stack = gen_reg_rtx (Pmode);
+  rtx tocompare = gen_reg_rtx (SImode);
+  rtx opcode = gen_reg_rtx (SImode);
+  rtx opcode_addr = gen_reg_rtx (Pmode);
+  rtx mem;
+  rtx loop_start = gen_label_rtx ();
+  rtx no_toc_restore_needed = gen_label_rtx ();
+  rtx loop_exit = gen_label_rtx ();
+  
+  mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
+  MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+  emit_move_insn (bottom_of_stack, mem);
+
+  top_of_stack = expand_binop (Pmode, add_optab, 
+                              bottom_of_stack, stacksize,
+                              NULL_RTX, 1, OPTAB_WIDEN);
+
+  emit_move_insn (tocompare, 
+                 GEN_INT (trunc_int_for_mode (TARGET_32BIT 
+                                              ? 0x80410014 
+                                              : 0xE8410028, SImode)));
+
+  if (insn_after_throw == NULL_RTX)
+    abort();
+  emit_move_insn (opcode, insn_after_throw);
+  
+  emit_note (NULL_PTR, NOTE_INSN_LOOP_BEG);
+  emit_label (loop_start);
+  
+  do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
+                          SImode, NULL_RTX, 0, NULL_RTX,
+                          no_toc_restore_needed);
+  
+  mem = gen_rtx_MEM (Pmode, 
+                    gen_rtx_PLUS (Pmode, bottom_of_stack, 
+                                  GEN_INT (5 * GET_MODE_SIZE (Pmode))));
+  emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
+
+  emit_label (no_toc_restore_needed);
+  do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
+                          Pmode, NULL_RTX, 0, NULL_RTX,
+                          loop_exit);
+
+  mem = gen_rtx_MEM (Pmode, bottom_of_stack);
+  MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+  emit_move_insn (bottom_of_stack, mem);
+  
+  mem = gen_rtx_MEM (Pmode, 
+                    gen_rtx_PLUS (Pmode, bottom_of_stack, 
+                                  GEN_INT (2 * GET_MODE_SIZE (Pmode))));
+  emit_move_insn (opcode_addr, mem);
+  emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
+
+  emit_note (NULL_PTR, NOTE_INSN_LOOP_CONT);
+  emit_jump (loop_start);
+  emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
+  emit_label (loop_exit);
+}
+#endif /* TARGET_AIX */
 \f
-/* Emit the correct code for allocating stack space.  If COPY_R12, make sure a copy
-   of the old frame is left in r12.  */
+/* This ties together stack memory 
+   (MEM with an alias set of rs6000_sr_alias_set)
+   and the change to the stack pointer.  */
+static void
+rs6000_emit_stack_tie ()
+{
+  rtx mem;
+  mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
+  MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+  emit_insn (gen_stack_tie (mem));
+}
 
-void
-rs6000_allocate_stack_space (file, size, copy_r12)
-     FILE *file;
-     int size;
+/* Emit the correct code for allocating stack space, as insns.
+   If COPY_R12, make sure a copy of the old frame is left in r12.
+   The generated code may use hard register 0 as a temporary.  */
+
+static void
+rs6000_emit_allocate_stack (size, copy_r12)
+     HOST_WIDE_INT size;
      int copy_r12;
 {
-  int neg_size = -size;
+  rtx insn;
+  rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+  rtx tmp_reg = gen_rtx_REG (Pmode, 0);
+  rtx todec = GEN_INT (-size);
 
   if (current_function_limit_stack)
     {
@@ -4187,111 +4679,400 @@ rs6000_allocate_stack_space (file, size, copy_r12)
          && REGNO (stack_limit_rtx) > 1 
          && REGNO (stack_limit_rtx) <= 31)
        {
-         if (size <= 32767)
-           asm_fprintf (file, "\t{cal %s,%d(%s)|addi %s,%s,%d}\n",
-                        reg_names[0], reg_names[REGNO (stack_limit_rtx)], 
-                        size);
-         else
-           {
-             asm_fprintf (file, "\t{cau|addis} %s,%s,0x%x\n",
-                          reg_names[0], reg_names[REGNO (stack_limit_rtx)], 
-                          ((size + 0x8000) >> 16) & 0xffff);
-             asm_fprintf (file, "\t{ai|addic} %s,%s,%d\n",
-                          reg_names[0], reg_names[0], 
-                          (size & 0x7fff) | -(size & 0x8000));
-           }
-         if (TARGET_32BIT)
-           asm_fprintf (file, "\t{t|tw}llt %s,%s\n", 
-                        reg_names[1], reg_names[0]);
-         else
-           asm_fprintf (file, "\ttdllt %s,%s\n", reg_names[1], reg_names[0]);
+         emit_insn (Pmode == SImode
+                    ? gen_addsi3 (tmp_reg,
+                                  stack_limit_rtx,
+                                  GEN_INT (size))
+                    : gen_adddi3 (tmp_reg,
+                                  stack_limit_rtx,
+                                  GEN_INT (size)));
+         
+         emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
+                                   const0_rtx));
        }
       else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
+              && TARGET_32BIT
               && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
        {
-         const char * l_name = XSTR (stack_limit_rtx, 0);
-         const char * stripped_name;
-
-         STRIP_NAME_ENCODING (stripped_name, l_name);
-         asm_fprintf (file, "\t{liu|lis} %s,%s@ha+%d\n",
-                      reg_names[0], stripped_name, size);
-         asm_fprintf (file, "\t{ai|addic} %s,%s,%s@l+%d\n",
-                      reg_names[0], reg_names[0], stripped_name, size);
-         if (TARGET_32BIT)
-           asm_fprintf (file, "\t{t|tw}llt %s,%s\n", 
-                        reg_names[1], reg_names[0]);
-         else
-           asm_fprintf (file, "\ttdllt %s,%s\n", reg_names[1], reg_names[0]);
+         rtx toload = gen_rtx_CONST (VOIDmode,
+                                     gen_rtx_PLUS (Pmode, 
+                                                   stack_limit_rtx, 
+                                                   GEN_INT (size)));
+         
+         emit_insn (gen_elf_high (tmp_reg, toload));
+         emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
+         emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
+                                   const0_rtx));
        }
       else
        warning ("stack limit expression is not supported");
     }
 
+  if (copy_r12 || ! TARGET_UPDATE)
+    emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
+
   if (TARGET_UPDATE)
     {
-      if (size < 32767)
-       asm_fprintf (file,
-                    (TARGET_32BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n",
-                    reg_names[1], neg_size, reg_names[1]);
-      else
+      if (size > 32767)
        {
-         if (copy_r12)
-           fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
-
-         asm_fprintf (file, "\t{liu|lis} %s,0x%x\n\t{oril|ori} %s,%s,%d\n",
-                      reg_names[0], (neg_size >> 16) & 0xffff,
-                      reg_names[0], reg_names[0], neg_size & 0xffff);
-         asm_fprintf (file,
-                      (TARGET_32BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n",
-                      reg_names[1], reg_names[1], reg_names[0]);
+         /* Need a note here so that try_split doesn't get confused.  */
+         if (get_last_insn() == NULL_RTX)
+           emit_note (0, NOTE_INSN_DELETED);
+         insn = emit_move_insn (tmp_reg, todec);
+         try_split (PATTERN (insn), insn, 0);
+         todec = tmp_reg;
        }
+      
+      if (Pmode == SImode)
+       insn = emit_insn (gen_movsi_update (stack_reg, stack_reg, 
+                                           todec, stack_reg));
+      else
+       insn = emit_insn (gen_movdi_update (stack_reg, stack_reg, 
+                                           todec, stack_reg));
     }
   else
     {
-      fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
-      if (size < 32767)
-       asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n",
-                reg_names[1], neg_size, reg_names[1]);
+      if (Pmode == SImode)
+       insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
       else
+       insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
+      emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
+                     gen_rtx_REG (Pmode, 12));
+    }
+  
+  RTX_FRAME_RELATED_P (insn) = 1;
+  REG_NOTES (insn) = 
+    gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+                      gen_rtx_SET (VOIDmode, stack_reg, 
+                                   gen_rtx_PLUS (Pmode, stack_reg,
+                                                 GEN_INT (-size))),
+                      REG_NOTES (insn));
+}
+
+/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced with
+   (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2 is not 
+   NULL.  
+   It would be nice if dwarf2out_frame_debug_expr could deduce these
+   equivalences by itself so it wasn't necessary to hold its hand so much.  */
+
+static void
+rs6000_frame_related (insn, reg, val, reg2, rreg)
+     rtx insn;
+     rtx reg;
+     HOST_WIDE_INT val;
+     rtx reg2;
+     rtx rreg;
+{
+  rtx real, temp;
+
+  real = copy_rtx (PATTERN (insn));
+
+  real = replace_rtx (real, reg, 
+                     gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
+                                                       STACK_POINTER_REGNUM),
+                                   GEN_INT (val)));
+  
+  /* We expect that 'real' is either a SET or a PARALLEL containing
+     SETs (and possibly other stuff).  In a PARALLEL, all the SETs
+     are important so they all have to be marked RTX_FRAME_RELATED_P.  */
+
+  if (GET_CODE (real) == SET)
+    {
+      rtx set = real;
+      
+      temp = simplify_rtx (SET_SRC (set));
+      if (temp)
+       SET_SRC (set) = temp;
+      temp = simplify_rtx (SET_DEST (set));
+      if (temp)
+       SET_DEST (set) = temp;
+      if (GET_CODE (SET_DEST (set)) == MEM)
        {
-         asm_fprintf (file, "\t{liu|lis} %s,0x%x\n\t{oril|ori} %s,%s,%d\n",
-                      reg_names[0], (neg_size >> 16) & 0xffff,
-                      reg_names[0], reg_names[0], neg_size & 0xffff);
-         asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", reg_names[1],
-                      reg_names[0], reg_names[1]);
+         temp = simplify_rtx (XEXP (SET_DEST (set), 0));
+         if (temp)
+           XEXP (SET_DEST (set), 0) = temp;
        }
-
-      asm_fprintf (file,
-                  (TARGET_32BIT) ? "\t{st|stw} %s,0(%s)\n" : "\tstd %s,0(%s)\n",
-                  reg_names[12], reg_names[1]);
     }
+  else if (GET_CODE (real) == PARALLEL)
+    {
+      int i;
+      for (i = 0; i < XVECLEN (real, 0); i++)
+       if (GET_CODE (XVECEXP (real, 0, i)) == SET)
+         {
+           rtx set = XVECEXP (real, 0, i);
+           
+           temp = simplify_rtx (SET_SRC (set));
+           if (temp)
+             SET_SRC (set) = temp;
+           temp = simplify_rtx (SET_DEST (set));
+           if (temp)
+             SET_DEST (set) = temp;
+           if (GET_CODE (SET_DEST (set)) == MEM)
+             {
+               temp = simplify_rtx (XEXP (SET_DEST (set), 0));
+               if (temp)
+                 XEXP (SET_DEST (set), 0) = temp;
+             }
+           RTX_FRAME_RELATED_P (set) = 1;
+         }
+    }
+  else
+    abort();
+  
+  if (reg2 != NULL_RTX)
+    real = replace_rtx (real, reg2, rreg);
+  
+  RTX_FRAME_RELATED_P (insn) = 1;
+  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+                                       real,
+                                       REG_NOTES (insn));
 }
 
-\f
-/* Write function prologue.  */
+/* Emit function prologue as insns.  */
+
 void
-output_prolog (file, size)
-     FILE *file;
-     int size ATTRIBUTE_UNUSED;
+rs6000_emit_prologue()
 {
   rs6000_stack_t *info = rs6000_stack_info ();
-  int reg_size = info->reg_size;
-  const char *store_reg;
-  const char *load_reg;
-  int sp_reg = 1;
-  int sp_offset = 0;
+  enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
+  int reg_size = TARGET_POWERPC64 ? 8 : 4;
+  rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+  rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
+  rtx frame_reg_rtx = sp_reg_rtx;
+  rtx cr_save_rtx = NULL;
+  rtx insn;
+  int saving_FPRs_inline;
+  int using_store_multiple;
+  HOST_WIDE_INT sp_offset = 0;
+  
+  using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
+                         && info->first_gp_reg_save < 31);
+  saving_FPRs_inline = (info->first_fp_reg_save == 64
+                       || FP_SAVE_INLINE (info->first_fp_reg_save));
+
+  /* For V.4, update stack before we do any saving and set back pointer.  */
+  if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
+    {
+      if (info->total_size < 32767)
+       sp_offset = info->total_size;
+      else
+       frame_reg_rtx = frame_ptr_rtx;
+      rs6000_emit_allocate_stack (info->total_size, 
+                                 (frame_reg_rtx != sp_reg_rtx
+                                  && (info->cr_save_p
+                                      || info->lr_save_p
+                                      || info->first_fp_reg_save < 64
+                                      || info->first_gp_reg_save < 32
+                                      )));
+      if (frame_reg_rtx != sp_reg_rtx)
+       rs6000_emit_stack_tie ();
+    }
+
+  /* If we use the link register, get it into r0.  */
+  if (info->lr_save_p)
+    emit_move_insn (gen_rtx_REG (Pmode, 0), 
+                   gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
+
+  /* If we need to save CR, put it into r12.  */
+  if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
+    {
+      cr_save_rtx = gen_rtx_REG (SImode, 12);
+      emit_insn (gen_movesi_from_cr (cr_save_rtx));
+    }
+
+  /* Do any required saving of fpr's.  If only one or two to save, do it
+     ourself.  Otherwise, call function.  */
+  if (saving_FPRs_inline)
+    {
+      int i;
+      for (i = 0; i < 64 - info->first_fp_reg_save; i++)
+       if ((regs_ever_live[info->first_fp_reg_save+i] 
+            && ! call_used_regs[info->first_fp_reg_save+i]))
+         {
+           rtx addr, reg, mem;
+           reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+           addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                                GEN_INT (info->fp_save_offset 
+                                         + sp_offset 
+                                         + 8*i));
+           mem = gen_rtx_MEM (DFmode, addr);
+           MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+           insn = emit_move_insn (mem, reg);
+           rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
+                                 NULL_RTX, NULL_RTX);
+         }
+    }
+  else if (info->first_fp_reg_save != 64)
+    {
+      int i;
+      char rname[30];
+      char *alloc_rname;
+      rtvec p;
+      p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
+      
+      RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode, 
+                                         gen_rtx_REG (Pmode, 
+                                                      LINK_REGISTER_REGNUM));
+      sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
+              info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
+      alloc_rname = ggc_alloc_string (rname, -1);
+      RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
+                                     gen_rtx_SYMBOL_REF (Pmode,
+                                                         alloc_rname));
+      for (i = 0; i < 64 - info->first_fp_reg_save; i++)
+       {
+         rtx addr, reg, mem;
+         reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+         addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                              GEN_INT (info->fp_save_offset 
+                                       + sp_offset + 8*i));
+         mem = gen_rtx_MEM (DFmode, addr);
+         MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+         RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
+       }
+      insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+      rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
+                           NULL_RTX, NULL_RTX);
+    }
 
-  if (TARGET_32BIT)
+  /* Save GPRs.  This is done as a PARALLEL if we are using
+     the store-multiple instructions.  */
+  if (using_store_multiple)
     {
-      store_reg = "\t{st|stw} %s,%d(%s)\n";
-      load_reg = "\t{l|lwz} %s,%d(%s)\n";
+      rtvec p, dwarfp;
+      int i;
+      p = rtvec_alloc (32 - info->first_gp_reg_save);
+      dwarfp = rtvec_alloc (32 - info->first_gp_reg_save);
+      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+       {
+         rtx addr, reg, mem;
+         reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
+         addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
+                              GEN_INT (info->gp_save_offset 
+                                       + sp_offset 
+                                       + reg_size * i));
+         mem = gen_rtx_MEM (reg_mode, addr);
+         MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+         RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
+       }
+      insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+      rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
+                           NULL_RTX, NULL_RTX);
     }
   else
     {
-      store_reg = "\tstd %s,%d(%s)\n";
-      load_reg = "\tlld %s,%d(%s)\n";
+      int i;
+      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+       if ((regs_ever_live[info->first_gp_reg_save+i] 
+            && ! call_used_regs[info->first_gp_reg_save+i])
+           || (i+info->first_gp_reg_save == PIC_OFFSET_TABLE_REGNUM
+               && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
+               && flag_pic == 1))
+         {
+           rtx addr, reg, mem;
+           reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
+           addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
+                                GEN_INT (info->gp_save_offset 
+                                         + sp_offset 
+                                         + reg_size * i));
+           mem = gen_rtx_MEM (reg_mode, addr);
+           MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+           insn = emit_move_insn (mem, reg);
+           rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
+                                 NULL_RTX, NULL_RTX);
+         }
+    }
+
+  /* Save lr if we used it.  */
+  if (info->lr_save_p)
+    {
+      rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                              GEN_INT (info->lr_save_offset + sp_offset));
+      rtx reg = gen_rtx_REG (Pmode, 0);
+      rtx mem = gen_rtx_MEM (Pmode, addr);
+      /* This should not be of rs6000_sr_alias_set, because of
+        __builtin_return_address.  */
+      
+      insn = emit_move_insn (mem, reg);
+      rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
+                           reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
+    }
+
+  /* Save CR if we use any that must be preserved.  */
+  if (info->cr_save_p)
+    {
+      rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                              GEN_INT (info->cr_save_offset + sp_offset));
+      rtx mem = gen_rtx_MEM (SImode, addr);
+      MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+      /* If r12 was used to hold the original sp, copy cr into r0 now
+        that it's free.  */
+      if (REGNO (frame_reg_rtx) == 12)
+       {
+         cr_save_rtx = gen_rtx_REG (SImode, 0);
+         emit_insn (gen_movesi_from_cr (cr_save_rtx));
+       }
+      insn = emit_move_insn (mem, cr_save_rtx);
+
+      /* Now, there's no way that dwarf2out_frame_debug_expr is going
+        to understand '(unspec:SI [(reg:CC 68) ...] 19)'.  But that's
+        OK.  All we have to do is specify that _one_ condition code
+        register is saved in this stack slot.  The thrower's epilogue
+        will then restore all the call-saved registers.  */
+      rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
+                           cr_save_rtx, gen_rtx_REG (SImode, CR0_REGNO));
+    }
+
+  /* Update stack and set back pointer unless this is V.4, 
+     for which it was done previously.  */
+  if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
+    rs6000_emit_allocate_stack (info->total_size, FALSE);
+
+  /* Set frame pointer, if needed.  */
+  if (frame_pointer_needed)
+    {
+      insn = emit_move_insn (gen_rtx_REG (reg_mode, FRAME_POINTER_REGNUM), 
+                            sp_reg_rtx);
+      RTX_FRAME_RELATED_P (insn) = 1;
     }
 
+  /* If we are using PIC_OFFSET_TABLE_REGNUM, we need to set it up.  */
+  if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
+      || ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) 
+         && flag_pic == 1 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]))
+  {
+    /* If emit_load_toc_table will use the link register, we need to save
+       it.  We use R11 for this purpose because emit_load_toc_table
+       can use register 0.  This allows us to use a plain 'blr' to return
+       from the procedure more often.  */
+    int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0 && 
+                                   ! info->lr_save_p);
+    if (save_LR_around_toc_setup)
+      emit_move_insn (gen_rtx_REG (Pmode, 11), 
+                     gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
+    
+    rs6000_emit_load_toc_table (TRUE);
+
+    if (save_LR_around_toc_setup)
+      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), 
+                     gen_rtx_REG (Pmode, 11));
+  }
+}
+
+
+/* Write function prologue.  */
+void
+output_prolog (file, size)
+     FILE *file;
+     int size ATTRIBUTE_UNUSED;
+{
+  rs6000_stack_t *info = rs6000_stack_info ();
+
   if (TARGET_DEBUG_STACK)
     debug_stack_info (info);
 
@@ -4322,222 +5103,295 @@ output_prolog (file, size)
       common_mode_defined = 1;
     }
 
-  /* For V.4, update stack before we do any saving and set back pointer.  */
-  if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
+  if (! HAVE_prologue)
     {
-      if (info->total_size < 32767)
-       sp_offset = info->total_size;
-      else
-       sp_reg = 12;
-      rs6000_allocate_stack_space (file, info->total_size, sp_reg == 12);
+      start_sequence ();
+      
+      /* A NOTE_INSN_DELETED is supposed to be at the start
+        and end of the "toplevel" insn chain.  */
+      emit_note (0, NOTE_INSN_DELETED);
+      rs6000_emit_prologue ();
+      emit_note (0, NOTE_INSN_DELETED);
+      
+      if (TARGET_DEBUG_STACK)
+       debug_rtx_list (get_insns(), 100);
+      final (get_insns(), file, FALSE, FALSE);
+      end_sequence ();
     }
 
-  /* If we use the link register, get it into r0.  */
-  if (info->lr_save_p)
-    asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
+  rs6000_pic_labelno++;
+}
+  
+/* Emit function epilogue as insns.
 
-  /* If we need to save CR, put it into r12.  */
-  if (info->cr_save_p && sp_reg != 12)
-    asm_fprintf (file, "\tmfcr %s\n", reg_names[12]);
+   At present, dwarf2out_frame_debug_expr doesn't understand
+   register restores, so we don't bother setting RTX_FRAME_RELATED_P
+   anywhere in the epilogue.  Most of the insns below would in any case
+   need special notes to explain where r11 is in relation to the stack.  */
 
-  /* Do any required saving of fpr's.  If only one or two to save, do it
-     ourself.  Otherwise, call function.  Note that since they are statically
-     linked, we do not need a nop following them.  */
-  if (FP_SAVE_INLINE (info->first_fp_reg_save))
+void
+rs6000_emit_epilogue(sibcall)
+     int sibcall;
+{
+  rs6000_stack_t *info;
+  int restoring_FPRs_inline;
+  int using_load_multiple;
+  int using_mfcr_multiple;
+  int use_backchain_to_restore_sp;
+  int sp_offset = 0;
+  rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
+  rtx frame_reg_rtx = sp_reg_rtx;
+  enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
+  int reg_size = TARGET_POWERPC64 ? 8 : 4;
+  int i;
+
+  info = rs6000_stack_info ();
+  using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
+                        && info->first_gp_reg_save < 31);
+  restoring_FPRs_inline = (sibcall
+                          || info->first_fp_reg_save == 64
+                          || FP_SAVE_INLINE (info->first_fp_reg_save));
+  use_backchain_to_restore_sp = (frame_pointer_needed 
+                                || current_function_calls_alloca
+                                || info->total_size > 32767);
+  using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
+                        || rs6000_cpu == PROCESSOR_PPC603
+                        || rs6000_cpu == PROCESSOR_PPC750
+                        || optimize_size);
+
+  /* If we have a frame pointer, a call to alloca,  or a large stack
+     frame, restore the old stack pointer using the backchain.  Otherwise,
+     we know what size to update it with.  */
+  if (use_backchain_to_restore_sp)
     {
-      int regno = info->first_fp_reg_save;
-      int loc   = info->fp_save_offset + sp_offset;
+      /* Under V.4, don't reset the stack pointer until after we're done
+        loading the saved registers.  */
+      if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
+       frame_reg_rtx = gen_rtx_REG (Pmode, 11);
 
-      for ( ; regno < 64; regno++, loc += 8)
-       asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]);
+      emit_move_insn (frame_reg_rtx,
+                     gen_rtx_MEM (Pmode, sp_reg_rtx));
+      
     }
-  else if (info->first_fp_reg_save != 64)
-    asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX,
-                info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
-
-  /* Now save gpr's.  */
-  if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT)
+  else if (info->push_p)
     {
-      int regno    = info->first_gp_reg_save;
-      int loc      = info->gp_save_offset + sp_offset;
-
-      for ( ; regno < 32; regno++, loc += reg_size)
-       asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]);
+      if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
+       sp_offset = info->total_size;
+      else
+       {
+         emit_insn (TARGET_32BIT
+                    ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
+                                  GEN_INT (info->total_size))
+                    : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
+                                  GEN_INT (info->total_size)));
+       }
     }
-
-  else if (info->first_gp_reg_save != 32)
-    asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n",
-                reg_names[info->first_gp_reg_save],
-                info->gp_save_offset + sp_offset,
-                reg_names[sp_reg]);
-
-  /* Save main's arguments if we need to call a function */
-#ifdef NAME__MAIN
-  if (info->main_save_p)
+  
+  /* Get the old lr if we saved it.  */
+  if (info->lr_save_p)
     {
-      int regno;
-      int loc = info->main_save_offset + sp_offset;
-      int size = info->main_size;
+      rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                              GEN_INT (info->lr_save_offset + sp_offset));
+      rtx mem = gen_rtx_MEM (Pmode, addr);
+      MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
 
-      for (regno = 3; size > 0; regno++, loc += reg_size, size -= reg_size)
-       asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]);
+      emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
     }
-#endif
+  
+  /* Get the old cr if we saved it.  */
+  if (info->cr_save_p)
+    {
+      rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                              GEN_INT (info->cr_save_offset + sp_offset));
+      rtx mem = gen_rtx_MEM (SImode, addr);
+      MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
 
-  /* Save lr if we used it.  */
+      emit_move_insn (gen_rtx_REG (SImode, 12), mem);
+    }
+  
+  /* Set LR here to try to overlap restores below.  */
   if (info->lr_save_p)
-    asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset + sp_offset,
-                reg_names[sp_reg]);
-
-  /* Save CR if we use any that must be preserved.  */
-  if (info->cr_save_p)
+    emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
+                   gen_rtx_REG (Pmode, 0));
+  
+  
+  /* Restore GPRs.  This is done as a PARALLEL if we are using
+     the load-multiple instructions.  */
+  if (using_load_multiple)
     {
-      if (sp_reg == 12)        /* If r12 is used to hold the original sp, copy cr now */
+      rtvec p;
+      p = rtvec_alloc (32 - info->first_gp_reg_save);
+      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
        {
-         asm_fprintf (file, "\tmfcr %s\n", reg_names[0]);
-         asm_fprintf (file, store_reg, reg_names[0],
-                      info->cr_save_offset + sp_offset,
-                      reg_names[sp_reg]);
+         rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
+                                  GEN_INT (info->gp_save_offset 
+                                           + sp_offset 
+                                           + reg_size * i));
+         rtx mem = gen_rtx_MEM (reg_mode, addr);
+         MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+         RTVEC_ELT (p, i) = 
+           gen_rtx_SET (VOIDmode,
+                        gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
+                        mem);
        }
-      else
-       asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset,
-                    reg_names[sp_reg]);
+      emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
     }
+  else
+    for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+      if ((regs_ever_live[info->first_gp_reg_save+i] 
+          && ! call_used_regs[info->first_gp_reg_save+i])
+         || (i+info->first_gp_reg_save == PIC_OFFSET_TABLE_REGNUM
+             && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
+             && flag_pic == 1))
+       {
+         rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
+                                  GEN_INT (info->gp_save_offset 
+                                           + sp_offset 
+                                           + reg_size * i));
+         rtx mem = gen_rtx_MEM (reg_mode, addr);
+         MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+         emit_move_insn (gen_rtx_REG (reg_mode, 
+                                      info->first_gp_reg_save + i),
+                         mem);
+       }
 
-  /* If we need PIC_OFFSET_TABLE_REGNUM, initialize it now */
-  if ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) 
-      && flag_pic == 1 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
-    {
-      if (! info->lr_save_p)
-       asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
-
-      fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
-      asm_fprintf (file, "\tmflr %s\n", reg_names[PIC_OFFSET_TABLE_REGNUM]);
-
-      if (! info->lr_save_p)
-       asm_fprintf (file, "\tmtlr %s\n", reg_names[0]);
-    }
+  /* Restore fpr's if we need to do it without calling a function.  */
+  if (restoring_FPRs_inline)
+    for (i = 0; i < 64 - info->first_fp_reg_save; i++)
+      if ((regs_ever_live[info->first_fp_reg_save+i] 
+          && ! call_used_regs[info->first_fp_reg_save+i]))
+       {
+         rtx addr, mem;
+         addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                              GEN_INT (info->fp_save_offset 
+                                       + sp_offset 
+                                       + 8*i));
+         mem = gen_rtx_MEM (DFmode, addr);
+         MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+         emit_move_insn (gen_rtx_REG (DFmode, 
+                                      info->first_fp_reg_save + i),
+                         mem);
+       }
 
-  /* NT needs us to probe the stack frame every 4k pages for large frames, so
-     do it here.  */
-  if (DEFAULT_ABI == ABI_NT && info->total_size > 4096)
+  /* If we saved cr, restore it here.  Just those that were used.  */
+  if (info->cr_save_p)
     {
-      if (info->total_size < 32768)
+      rtx r12_rtx = gen_rtx_REG (SImode, 12);
+      
+      if (using_mfcr_multiple)
        {
-         int probe_offset = 4096;
-         while (probe_offset < info->total_size)
-           {
-             asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", reg_names[0], -probe_offset, reg_names[1]);
-             probe_offset += 4096;
-           }
+         rtvec p;
+         int mask = 0;
+         int count = 0;
+
+         for (i = 0; i < 8; i++)
+           if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
+             {
+               mask |= 1 << (7-i);
+               count++;
+             }
+         if (count == 0)
+           abort();
+         
+         p = rtvec_alloc (count + 1);
+
+         RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode, GEN_INT (mask));
+         count = 1;
+         for (i = 0; i < 8; i++)
+           if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
+             {
+               rtvec r = rtvec_alloc (2);
+               RTVEC_ELT (r, 0) = r12_rtx;
+               RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
+               RTVEC_ELT (p, count) =
+                 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), 
+                              gen_rtx_UNSPEC (CCmode, r, 20));
+               count++;
+             }
+         emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
        }
       else
-       {
-         int probe_iterations = info->total_size / 4096;
-         static int probe_labelno = 0;
-         char buf[256];
-
-         if (probe_iterations < 32768)
-           asm_fprintf (file, "\tli %s,%d\n", reg_names[12], probe_iterations);
-         else
+       for (i = 0; i < 8; i++)
+         if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
            {
-             asm_fprintf (file, "\tlis %s,%d\n", reg_names[12], probe_iterations >> 16);
-             if (probe_iterations & 0xffff)
-               asm_fprintf (file, "\tori %s,%s,%d\n", reg_names[12], reg_names[12],
-                            probe_iterations & 0xffff);
+             emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, 
+                                                          CR0_REGNO+i),
+                                             r12_rtx));
            }
-         asm_fprintf (file, "\tmtctr %s\n", reg_names[12]);
-         asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
-         ASM_OUTPUT_INTERNAL_LABEL (file, "LCprobe", probe_labelno);
-         asm_fprintf (file, "\t{lu|lwzu} %s,-4096(%s)\n", reg_names[0], reg_names[12]);
-         ASM_GENERATE_INTERNAL_LABEL (buf, "LCprobe", probe_labelno++);
-         fputs ("\tbdnz ", file);
-         assemble_name (file, buf);
-         putc ('\n', file);
-       }
     }
 
-  /* Update stack and set back pointer unless this is V.4, which was done previously */
-  if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
-    rs6000_allocate_stack_space (file, info->total_size, FALSE);
-
-  /* Set frame pointer, if needed.  */
-  if (frame_pointer_needed)
-    asm_fprintf (file, "\tmr %s,%s\n", reg_names[31], reg_names[1]);
-
-#ifdef NAME__MAIN
-  /* If we need to call a function to set things up for main, do so now
-     before dealing with the TOC.  */
-  if (info->main_p)
+  /* If this is V.4, unwind the stack pointer after all of the loads
+     have been done.  We need to emit a block here so that sched
+     doesn't decide to move the sp change before the register restores
+     (which may not have any obvious dependency on the stack).  This
+     doesn't hurt performance, because there is no scheduling that can
+     be done after this point.  */
+  if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
     {
-      const char *prefix = "";
+      if (frame_reg_rtx != sp_reg_rtx)
+         rs6000_emit_stack_tie ();
 
-      switch (DEFAULT_ABI)
+      if (use_backchain_to_restore_sp)
        {
-       case ABI_AIX:   prefix = ".";   break;
-       case ABI_NT:    prefix = "..";  break;
+         emit_move_insn (sp_reg_rtx, frame_reg_rtx);
        }
-
-      fprintf (file, "\tbl %s%s\n", prefix, NAME__MAIN);
-#ifdef RS6000_CALL_GLUE2
-      fprintf (file, "\t%s%s%s\n", RS6000_CALL_GLUE2, prefix, NAME_MAIN);
-#else
-#ifdef RS6000_CALL_GLUE
-      if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+      else if (sp_offset != 0)
        {
-         putc('\t', file);
-         asm_fprintf (file, RS6000_CALL_GLUE);
-         putc('\n', file);
+         emit_insn (Pmode == SImode
+                    ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
+                                  GEN_INT (sp_offset))
+                    : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
+                                  GEN_INT (sp_offset)));
        }
-#endif
-#endif
+    }
 
-      if (info->main_save_p)
-       {
-         int regno;
-         int loc;
-         int size = info->main_size;
+  if (!sibcall)
+    {
+      rtvec p;
+      if (! restoring_FPRs_inline)
+       p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
+      else
+       p = rtvec_alloc (2);
 
-         if (info->total_size < 32767)
-           {
-             loc = info->total_size + info->main_save_offset;
-             for (regno = 3; size > 0; regno++, size -= reg_size, loc += reg_size)
-               asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]);
-           }
-         else
-           {
-             int neg_size = info->main_save_offset - info->total_size;
-             loc = 0;
-             asm_fprintf (file, "\t{liu|lis} %s,0x%x\n\t{oril|ori} %s,%s,%d\n",
-                          reg_names[0], (neg_size >> 16) & 0xffff,
-                          reg_names[0], reg_names[0], neg_size & 0xffff);
+      RTVEC_ELT (p, 0) = gen_rtx_USE (VOIDmode, 
+                                     gen_rtx_REG (Pmode, 
+                                                  LINK_REGISTER_REGNUM));
+      RTVEC_ELT (p, 1) = gen_rtx_RETURN (VOIDmode);
+
+      /* If we have to restore more than two FP registers, branch to the
+        restore function.  It will return to our caller.  */
+      if (! restoring_FPRs_inline)
+       {
+         int i;
+         char rname[30];
+         char *alloc_rname;
 
-             asm_fprintf (file, "\t{sf|subf} %s,%s,%s\n", reg_names[0], reg_names[0],
-                          reg_names[1]);
+         sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX, 
+                  info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
+         alloc_rname = ggc_alloc_string (rname, -1);
+         RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
+                                         gen_rtx_SYMBOL_REF (Pmode,
+                                                             alloc_rname));
 
-             for (regno = 3; size > 0; regno++, size -= reg_size, loc += reg_size)
-               asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[0]);
+         for (i = 0; i < 64 - info->first_fp_reg_save; i++)
+           {
+             rtx addr, mem;
+             addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
+                                  GEN_INT (info->fp_save_offset + 8*i));
+             mem = gen_rtx_MEM (DFmode, addr);
+             MEM_ALIAS_SET (mem) = rs6000_sr_alias_set;
+
+             RTVEC_ELT (p, i+3) = 
+               gen_rtx_SET (VOIDmode,
+                            gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
+                            mem);
            }
        }
-    }
-#endif
-
-
-  /* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the
-     TOC_TABLE address into register 30.  */
-  if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
-    {
-#ifdef USING_SVR4_H
-      if (! profile_flag)
-       rs6000_pic_func_labelno = rs6000_pic_labelno;
-#endif
-      rs6000_output_load_toc_table (file, 30);
-    }
-
-  if (DEFAULT_ABI == ABI_NT)
-    {
-      assemble_name (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
-      fputs (".b:\n", file);
+      
+      emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
     }
 }
 
@@ -4549,101 +5403,31 @@ output_epilog (file, size)
      int size ATTRIBUTE_UNUSED;
 {
   rs6000_stack_t *info = rs6000_stack_info ();
-  const char *load_reg = (TARGET_32BIT) ? "\t{l|lwz} %s,%d(%s)\n" : "\tld %s,%d(%s)\n";
-  rtx insn = get_last_insn ();
-  int sp_reg = 1;
-  int sp_offset = 0;
 
-  /* If the last insn was a BARRIER, we don't have to write anything except
-     the trace table.  */
-  if (GET_CODE (insn) == NOTE)
-    insn = prev_nonnote_insn (insn);
-  if (insn == 0 ||  GET_CODE (insn) != BARRIER)
+  if (! HAVE_epilogue)
     {
-      /* If we have a frame pointer, a call to alloca,  or a large stack
-        frame, restore the old stack pointer using the backchain.  Otherwise,
-        we know what size to update it with.  */
-      if (frame_pointer_needed || current_function_calls_alloca
-         || info->total_size > 32767)
-       {
-         /* Under V.4, don't reset the stack pointer until after we're done
-            loading the saved registers.  */
-         if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
-           sp_reg = 11;
-
-         asm_fprintf (file, load_reg, reg_names[sp_reg], 0, reg_names[1]);
-       }
-      else if (info->push_p)
-       {
-         if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
-           sp_offset = info->total_size;
-         else
-           asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n",
-                        reg_names[1], info->total_size, reg_names[1]);
-       }
-
-      /* Get the old lr if we saved it.  */
-      if (info->lr_save_p)
-       asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset + sp_offset, reg_names[sp_reg]);
-
-      /* Get the old cr if we saved it.  */
-      if (info->cr_save_p)
-       asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset + sp_offset, reg_names[sp_reg]);
-
-      /* Set LR here to try to overlap restores below.  */
-      if (info->lr_save_p)
-       asm_fprintf (file, "\tmtlr %s\n", reg_names[0]);
-
-      /* Restore gpr's.  */
-      if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT)
-       {
-         int regno    = info->first_gp_reg_save;
-         int loc      = info->gp_save_offset + sp_offset;
-         int reg_size = (TARGET_32BIT) ? 4 : 8;
-
-         for ( ; regno < 32; regno++, loc += reg_size)
-           asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[sp_reg]);
-       }
-
-      else if (info->first_gp_reg_save != 32)
-       asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n",
-                    reg_names[info->first_gp_reg_save],
-                    info->gp_save_offset + sp_offset,
-                    reg_names[sp_reg]);
-
-      /* Restore fpr's if we can do it without calling a function.  */
-      if (FP_SAVE_INLINE (info->first_fp_reg_save))
+      rtx insn = get_last_insn ();
+      /* If the last insn was a BARRIER, we don't have to write anything except
+        the trace table.  */
+      if (GET_CODE (insn) == NOTE)
+       insn = prev_nonnote_insn (insn);
+      if (insn == 0 ||  GET_CODE (insn) != BARRIER)
        {
-         int regno = info->first_fp_reg_save;
-         int loc   = info->fp_save_offset + sp_offset;
-
-         for ( ; regno < 64; regno++, loc += 8)
-           asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]);
+         /* This is slightly ugly, but at least we don't have two
+            copies of the epilogue-emitting code.  */
+         start_sequence ();
+
+         /* A NOTE_INSN_DELETED is supposed to be at the start
+            and end of the "toplevel" insn chain.  */
+         emit_note (0, NOTE_INSN_DELETED);
+         rs6000_emit_epilogue (FALSE);
+         emit_note (0, NOTE_INSN_DELETED);
+
+         if (TARGET_DEBUG_STACK)
+           debug_rtx_list (get_insns(), 100);
+         final (get_insns(), file, FALSE, FALSE);
+         end_sequence ();
        }
-
-      /* If we saved cr, restore it here.  Just those of cr2, cr3, and cr4
-        that were used.  */
-      if (info->cr_save_p)
-       asm_fprintf (file, "\tmtcrf %d,%s\n",
-                    (regs_ever_live[70] != 0) * 0x20
-                    + (regs_ever_live[71] != 0) * 0x10
-                    + (regs_ever_live[72] != 0) * 0x8, reg_names[12]);
-
-      /* If this is V.4, unwind the stack pointer after all of the loads
-        have been done */
-      if (sp_offset != 0)
-       asm_fprintf (file, "\t{cal|la} %s,%d(%s)\n",
-                    reg_names[1], sp_offset, reg_names[1]);
-      else if (sp_reg != 1)
-       asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]);
-
-      /* If we have to restore more than two FP registers, branch to the
-        restore function.  It will return to our caller.  */
-      if (info->first_fp_reg_save != 64 && !FP_SAVE_INLINE (info->first_fp_reg_save))
-       asm_fprintf (file, "\tb %s%d%s\n", RESTORE_FP_PREFIX,
-                    info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
-      else
-       asm_fprintf (file, "\t{br|blr}\n");
     }
 
   /* Output a traceback table here.  See /usr/include/sys/debug.h for info
@@ -4820,9 +5604,17 @@ output_epilog (file, size)
       /* Offset from start of code to tb table.  */
       fputs ("\t.long ", file);
       ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
+#if TARGET_AIX
       RS6000_OUTPUT_BASENAME (file, fname);
+#else
+      assemble_name (file, fname);
+#endif
       fputs ("-.", file);
+#if TARGET_AIX
       RS6000_OUTPUT_BASENAME (file, fname);
+#else
+      assemble_name (file, fname);
+#endif
       putc ('\n', file);
 
       /* Interrupt handler mask.  */
@@ -4846,14 +5638,6 @@ output_epilog (file, size)
       if (frame_pointer_needed)
        fputs ("\t.byte 31\n", file);
     }
-
-  if (DEFAULT_ABI == ABI_NT)
-    {
-      RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
-      fputs (".e:\nFE_MOT_RESVD..", file);
-      RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
-      fputs (":\n", file);
-    }
 }
 \f
 /* A C compound statement that outputs the assembler code for a thunk function,
@@ -4897,7 +5681,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
   const char *prefix;
   const char *fname;
   const char *r0        = reg_names[0];
-  const char *sp        = reg_names[1];
   const char *toc       = reg_names[2];
   const char *schain    = reg_names[11];
   const char *r12       = reg_names[12];
@@ -4959,10 +5742,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
     case ABI_SOLARIS:
       prefix = "";
       break;
-
-    case ABI_NT:
-      prefix = "..";
-      break;
     }
 
   /* If the function is compiled in this module, jump to it directly.
@@ -4970,7 +5749,7 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
 
   fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
 
-  if (current_file_function_operand (XEXP (DECL_RTL (function), 0))
+  if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
       && ! lookup_attribute ("longcall",
                             TYPE_ATTRIBUTES (TREE_TYPE (function))))
     {
@@ -4985,7 +5764,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
       switch (DEFAULT_ABI)
        {
        default:
-       case ABI_NT:
          abort ();
 
        case ABI_AIX:
@@ -5022,71 +5800,192 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
          asm_fprintf (file, "\tbctr\n");
          break;
 
+       case ABI_AIX_NODESC:
+       case ABI_SOLARIS:
        case ABI_V4:
          fprintf (file, "\tb %s", prefix);
          assemble_name (file, fname);
          if (flag_pic) fputs ("@plt", file);
          putc ('\n', file);
          break;
-             
-         /* Don't use r11, that contains the static chain, just use r0/r12.  */
-       case ABI_AIX_NODESC:
-       case ABI_SOLARIS:
-         if (flag_pic == 1)
-           {
-             fprintf (file, "\tmflr %s\n", r0);
-             fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
-             asm_fprintf (file, "\tmflr %s\n", r12);
-             asm_fprintf (file, "\tmtlr %s\n", r0);
-             asm_fprintf (file, "\t{l|lwz} %s,", r0);
-             assemble_name (file, fname);
-             asm_fprintf (file, "@got(%s)\n", r12);
-             asm_fprintf (file, "\tmtctr %s\n", r0);
-             asm_fprintf (file, "\tbctr\n");
-           }
-#if TARGET_ELF
-         else if (flag_pic > 1 || TARGET_RELOCATABLE)
-           {
-             ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
-             labelno++;
-             fprintf (file, "\tmflr %s\n", r0);
-             asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", r0, sp);
-             rs6000_pic_func_labelno = rs6000_pic_labelno;
-             rs6000_output_load_toc_table (file, 12);
-             asm_fprintf (file, "\t{l|lwz} %s,", r0);
-             assemble_name (file, buf);
-             asm_fprintf (file, "(%s)\n", r12);
-             asm_fprintf (file, "\t{l|lwz} %s,4(%s)\n", r12, sp);
-             asm_fprintf (file, "\tmtlr %s\n", r12);
-             asm_fprintf (file, "\tmtctr %s\n", r0);
-             asm_fprintf (file, "\tbctr\n");
-             asm_fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
-             assemble_name (file, buf);
-             fputs (" = .-.LCTOC1\n", file);
-             fputs ("\t.long ", file);
-             assemble_name (file, fname);
-             fputs ("\n\t.previous\n", file);
-           }
-#endif /* TARGET_ELF */
+       }
+    }
+}
 
-         else
-           {
-             asm_fprintf (file, "\t{liu|lis} %s,", r12);
-             assemble_name (file, fname);
-             asm_fprintf (file, "@ha\n");
-             asm_fprintf (file, "\t{cal|la} %s,", r12);
-             assemble_name (file, fname);
-             asm_fprintf (file, "@l(%s)\n", r12);
-             asm_fprintf (file, "\tmtctr %s\n", r12);
-             asm_fprintf (file, "\tbctr\n");
-           }
+\f
+/* A quick summary of the various types of 'constant-pool tables'
+   under PowerPC:
+
+   Target      Flags           Name            One table per   
+   AIX         (none)          AIX TOC         object file
+   AIX         -mfull-toc      AIX TOC         object file
+   AIX         -mminimal-toc   AIX minimal TOC translation unit
+   SVR4/EABI   (none)          SVR4 SDATA      object file
+   SVR4/EABI   -fpic           SVR4 pic        object file
+   SVR4/EABI   -fPIC           SVR4 PIC        translation unit
+   SVR4/EABI   -mrelocatable   EABI TOC        function
+   SVR4/EABI   -maix           AIX TOC         object file
+   SVR4/EABI   -maix -mminimal-toc 
+                               AIX minimal TOC translation unit
+
+   Name                        Reg.    Set by  entries       contains:
+                                       made by  addrs? fp?     sum?
+
+   AIX TOC             2       crt0    as       Y      option  option
+   AIX minimal TOC     30      prolog  gcc      Y      Y       option
+   SVR4 SDATA          13      crt0    gcc      N      Y       N
+   SVR4 pic            30      prolog  ld       Y      not yet N
+   SVR4 PIC            30      prolog  gcc      Y      option  option
+   EABI TOC            30      prolog  gcc      Y      option  option
+
+*/
+
+/* Hash table stuff for keeping track of TOC entries.  */
+
+struct toc_hash_struct 
+{
+  /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
+     ASM_OUTPUT_SPECIAL_POOL_ENTRY_P.  */
+  rtx key;
+  int labelno;
+};
 
+static htab_t toc_hash_table;
+
+/* Hash functions for the hash table.  */
+
+static unsigned
+rs6000_hash_constant (k)
+     rtx k;
+{
+  unsigned result = GET_CODE (k);
+  const char *format = GET_RTX_FORMAT (GET_CODE (k));
+  int flen = strlen (format);
+  int fidx;
+  
+  if (GET_CODE (k) == LABEL_REF)
+    return result * 1231 + XINT (XEXP (k, 0), 3);
+
+  if (GET_CODE (k) == CONST_DOUBLE)
+    fidx = 2;
+  else if (GET_CODE (k) == CODE_LABEL)
+    fidx = 3;
+  else
+    fidx = 0;
+
+  for (; fidx < flen; fidx++)
+    switch (format[fidx])
+      {
+      case 's':
+       {
+         unsigned i, len;
+         const char *str = XSTR (k, fidx);
+         len = strlen (str);
+         result = result * 613 + len;
+         for (i = 0; i < len; i++)
+           result = result * 613 + (unsigned) str[i];
          break;
        }
+      case 'u':
+      case 'e':
+       result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
+       break;
+      case 'i':
+      case 'n':
+       result = result * 613 + (unsigned) XINT (k, fidx);
+       break;
+      case 'w':
+       if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
+         result = result * 613 + (unsigned) XWINT (k, fidx);
+       else
+         {
+           size_t i;
+           for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
+             result = result * 613 + (unsigned) (XWINT (k, fidx)
+                                                 >> CHAR_BIT * i);
+         }
+       break;
+      default:
+       abort();
+      }
+  return result;
+}
+
+static unsigned
+toc_hash_function (hash_entry)
+     const void * hash_entry;
+{
+  return rs6000_hash_constant (((const struct toc_hash_struct *) 
+                               hash_entry)->key);
+}
+
+/* Compare H1 and H2 for equivalence.  */
+
+static int
+toc_hash_eq (h1, h2)
+     const void * h1;
+     const void * h2;
+{
+  rtx r1 = ((const struct toc_hash_struct *) h1)->key;
+  rtx r2 = ((const struct toc_hash_struct *) h2)->key;
+
+  /* Gotcha:  One of these const_doubles will be in memory.
+     The other may be on the constant-pool chain.
+     So rtx_equal_p will think they are different... */
+  if (r1 == r2)
+    return 1;
+  if (GET_CODE (r1) != GET_CODE (r2)
+      || GET_MODE (r1) != GET_MODE (r2))
+    return 0;
+  if (GET_CODE (r1) == CONST_DOUBLE)
+    {
+      int format_len = strlen (GET_RTX_FORMAT (CONST_DOUBLE));
+      int i;
+      for (i = 2; i < format_len; i++)
+       if (XWINT (r1, i) != XWINT (r2, i))
+         return 0;
+      
+      return 1;
     }
+  else if (GET_CODE (r1) == LABEL_REF)
+    return XINT (XEXP (r1, 0), 3) == XINT (XEXP (r2, 0), 3);
+  else
+    return rtx_equal_p (r1, r2);
+}
+
+/* Mark the hash table-entry HASH_ENTRY.  */
+
+static int
+toc_hash_mark_entry (hash_slot, unused)
+     void * hash_slot;
+     void * unused ATTRIBUTE_UNUSED;
+{
+  const struct toc_hash_struct * hash_entry = 
+    *(const struct toc_hash_struct **) hash_slot;
+  rtx r = hash_entry->key;
+  ggc_set_mark (hash_entry);
+  /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
+  if (GET_CODE (r) == LABEL_REF)
+    {
+      ggc_set_mark (r);
+      ggc_set_mark (XEXP (r, 0));
+    }
+  else
+    ggc_mark_rtx (r);
+  return 1;
+}
+
+/* Mark all the elements of the TOC hash-table *HT.  */
+
+static void
+toc_hash_mark_table (vht)
+     void *vht;
+{
+  htab_t *ht = vht;
+  
+  htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
 }
 
-\f
 /* Output a TOC entry.  We derive the entry name from what is
    being written.  */
 
@@ -5105,8 +6004,38 @@ output_toc (file, x, labelno)
   if (TARGET_NO_TOC)
     abort ();
 
-  /* if we're going to put a double constant in the TOC, make sure it's
-     aligned properly when strict alignment is on. */
+  /* When the linker won't eliminate them, don't output duplicate
+     TOC entries (this happens on AIX if there is any kind of TOC,
+     and on SVR4 under -fPIC or -mrelocatable).
+     This won't work if we are not garbage collecting, so 
+     we don't do it, sorry.  */
+  if (TARGET_TOC && ggc_p)
+    {
+      struct toc_hash_struct *h;
+      void * * found;
+      
+      h = ggc_alloc (sizeof (*h));
+      h->key = x;
+      h->labelno = labelno;
+      
+      found = htab_find_slot (toc_hash_table, h, 1);
+      if (*found == NULL)
+       *found = h;
+      else  /* This is indeed a duplicate.  
+              Set this label equal to that label.  */
+       {
+         fputs ("\t.set ", file);
+         ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
+         fprintf (file, "%d,", labelno);
+         ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
+         fprintf (file, "%d\n", ((*(const struct toc_hash_struct **) 
+                                             found)->labelno));
+         return;
+       }
+    }
+
+  /* If we're going to put a double constant in the TOC, make sure it's
+     aligned properly when strict alignment is on.  */
   if (GET_CODE (x) == CONST_DOUBLE
       && STRICT_ALIGNMENT
       && GET_MODE (x) == DFmode
@@ -5114,16 +6043,7 @@ output_toc (file, x, labelno)
     ASM_OUTPUT_ALIGN (file, 3);
   }
 
-
-  if (TARGET_ELF && TARGET_MINIMAL_TOC)
-    {
-      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
-      fprintf (file, "%d = .-", labelno);
-      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCTOC");
-      fputs ("1\n", file);
-    }
-  else
-    ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
+  ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
 
   /* Handle FP constants specially.  Note that if we have a minimal
      TOC, things we put here aren't actually in the TOC, so we can allow
@@ -5143,7 +6063,7 @@ output_toc (file, x, labelno)
            fprintf (file, "\t.llong 0x%lx%08lx\n", k[0], k[1]);
          else
            fprintf (file, "\t.tc FD_%lx_%lx[TC],0x%lx%08lx\n",
-                    k[0], k[1], k[0] & 0xffffffff, k[1] & 0xffffffff);
+                    k[0], k[1], k[0] & 0xffffffffu, k[1] & 0xffffffffu);
          return;
        }
       else
@@ -5266,7 +6186,7 @@ output_toc (file, x, labelno)
      section.  */
   if (! strncmp ("_vt.", name, 4))
     {
-      RS6000_OUTPUT_BASENAME (file, name);
+      assemble_name (file, name);
       if (offset < 0)
        fprintf (file, "%d", offset);
       else if (offset > 0)
@@ -5344,7 +6264,7 @@ output_ascii (file, p, n)
 
   /* Now close the string if we have written one.  Then end the line.  */
   if (to_close)
-    fprintf (file, to_close);
+    fputs (to_close, file);
 }
 \f
 /* Generate a unique section name for FILENAME for a section type
@@ -5362,10 +6282,10 @@ output_ascii (file, p, n)
 void
 rs6000_gen_section_name (buf, filename, section_desc)
      char **buf;
-     char *filename;
-     char *section_desc;
+     const char *filename;
+     const char *section_desc;
 {
-  char *q, *after_last_slash, *last_period = 0;
+  const char *q, *after_last_slash, *last_period = 0;
   char *p;
   int len;
 
@@ -5434,24 +6354,20 @@ output_function_profiler (file, labelno)
          assemble_name (file, buf);
          asm_fprintf (file, "@got(%s)\n", reg_names[12]);
        }
-#if TARGET_ELF
-      else if (flag_pic > 1 || TARGET_RELOCATABLE)
+      else if (flag_pic > 1)
        {
          asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
                       reg_names[0], reg_names[1]);
-         rs6000_pic_func_labelno = rs6000_pic_labelno;
-         rs6000_output_load_toc_table (file, 12);
-         asm_fprintf (file, "\t{l|lwz} %s,", reg_names[12]);
-         assemble_name (file, buf);
-         asm_fprintf (file, "X(%s)\n", reg_names[12]);
-         asm_fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
+         /* Now, we need to get the address of the label.  */
+         fputs ("\tbl 1f\n\t.long ", file);
          assemble_name (file, buf);
-         fputs ("X = .-.LCTOC1\n", file);
-         fputs ("\t.long ", file);
-         assemble_name (file, buf);
-         fputs ("\n\t.previous\n", file);
+         fputs ("-.\n1:", file);
+         asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
+         asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n", 
+                      reg_names[0], reg_names[11]);
+         asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
+                      reg_names[0], reg_names[0], reg_names[11]);
        }
-#endif
       else
        {
          asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
@@ -5631,68 +6547,6 @@ int get_issue_rate()
 }
 
 \f
-/* Output assembler code for a block containing the constant parts
-   of a trampoline, leaving space for the variable parts.
-
-   The trampoline should set the static chain pointer to value placed
-   into the trampoline and should branch to the specified routine.  */
-
-void
-rs6000_trampoline_template (file)
-     FILE *file;
-{
-  const char *sc = reg_names[STATIC_CHAIN_REGNUM];
-  const char *r0 = reg_names[0];
-  const char *r2 = reg_names[2];
-
-  switch (DEFAULT_ABI)
-    {
-    default:
-      abort ();
-
-    /* Under AIX, this is not code at all, but merely a data area,
-       since that is the way all functions are called.  The first word is
-       the address of the function, the second word is the TOC pointer (r2),
-       and the third word is the static chain value.  */
-    case ABI_AIX:
-      break;
-
-
-    /* V.4/eabi function pointers are just a single pointer, so we need to
-       do the full gory code to load up the static chain.  */
-    case ABI_V4:
-    case ABI_SOLARIS:
-    case ABI_AIX_NODESC:
-      break;
-
-  /* NT function pointers point to a two word area (real address, TOC)
-     which unfortunately does not include a static chain field.  So we
-     use the function field to point to ..LTRAMP1 and the toc field
-     to point to the whole table.  */
-    case ABI_NT:
-      if (STATIC_CHAIN_REGNUM == 0
-         || STATIC_CHAIN_REGNUM == 2
-         || TARGET_64BIT
-         || !TARGET_NEW_MNEMONICS)
-       abort ();
-
-      fprintf (file, "\t.ualong 0\n");                 /* offset  0 */
-      fprintf (file, "\t.ualong 0\n");                 /* offset  4 */
-      fprintf (file, "\t.ualong 0\n");                 /* offset  8 */
-      fprintf (file, "\t.ualong 0\n");                 /* offset 12 */
-      fprintf (file, "\t.ualong 0\n");                 /* offset 16 */
-      fprintf (file, "..LTRAMP1..0:\n");               /* offset 20 */
-      fprintf (file, "\tlwz %s,8(%s)\n", r0, r2);      /* offset 24 */
-      fprintf (file, "\tlwz %s,12(%s)\n", sc, r2);     /* offset 28 */
-      fprintf (file, "\tmtctr %s\n", r0);              /* offset 32 */
-      fprintf (file, "\tlwz %s,16(%s)\n", r2, r2);     /* offset 36 */
-      fprintf (file, "\tbctr\n");                      /* offset 40 */
-      break;
-    }
-
-  return;
-}
-
 /* Length in units of the trampoline for entering a nested function.  */
 
 int
@@ -5714,10 +6568,6 @@ rs6000_trampoline_size ()
     case ABI_AIX_NODESC:
       ret = (TARGET_32BIT) ? 40 : 48;
       break;
-
-    case ABI_NT:
-      ret = 20;
-      break;
     }
 
   return ret;
@@ -5771,27 +6621,6 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt)
                         fnaddr, pmode,
                         ctx_reg, pmode);
       break;
-
-    /* Under NT, update the first word to point to the ..LTRAMP1..0 header,
-       the second word will point to the whole trampoline, third-fifth words
-       will then have the real address, static chain, and toc value.  */
-    case ABI_NT:
-      {
-       rtx tramp_reg = gen_reg_rtx (pmode);
-       rtx fn_reg = gen_reg_rtx (pmode);
-       rtx toc_reg = gen_reg_rtx (pmode);
-
-       emit_move_insn (tramp_reg, gen_rtx_SYMBOL_REF (pmode, "..LTRAMP1..0"));
-       addr = force_reg (pmode, addr);
-       emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
-       emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
-       emit_move_insn (MEM_DEREF (addr), tramp_reg);
-       emit_move_insn (MEM_PLUS (addr, regsize), addr);
-       emit_move_insn (MEM_PLUS (addr, 2*regsize), fn_reg);
-       emit_move_insn (MEM_PLUS (addr, 3*regsize), ctx_reg);
-       emit_move_insn (MEM_PLUS (addr, 4*regsize), gen_rtx_REG (pmode, 2));
-      }
-      break;
     }
 
   return;
@@ -5833,51 +6662,6 @@ rs6000_valid_type_attribute_p (type, attributes, identifier, args)
   if (is_attribute_p ("longcall", identifier))
     return (args == NULL_TREE);
 
-  if (DEFAULT_ABI == ABI_NT)
-    {
-      /* Stdcall attribute says callee is responsible for popping arguments
-        if they are not variable.  */
-      if (is_attribute_p ("stdcall", identifier))
-       return (args == NULL_TREE);
-
-      /* Cdecl attribute says the callee is a normal C declaration */
-      if (is_attribute_p ("cdecl", identifier))
-       return (args == NULL_TREE);
-
-      /* Dllimport attribute says the caller is to call the function
-        indirectly through a __imp_<name> pointer.  */
-      if (is_attribute_p ("dllimport", identifier))
-       return (args == NULL_TREE);
-
-      /* Dllexport attribute says the callee is to create a __imp_<name>
-        pointer.  */
-      if (is_attribute_p ("dllexport", identifier))
-       return (args == NULL_TREE);
-
-      /* Exception attribute allows the user to specify 1-2 strings
-        or identifiers that will fill in the 3rd and 4th fields
-        of the structured exception table.  */
-      if (is_attribute_p ("exception", identifier))
-       {
-         int i;
-
-         if (args == NULL_TREE)
-           return 0;
-
-         for (i = 0; i < 2 && args != NULL_TREE; i++)
-           {
-             tree this_arg = TREE_VALUE (args);
-             args = TREE_PURPOSE (args);
-
-             if (TREE_CODE (this_arg) != STRING_CST
-                 && TREE_CODE (this_arg) != IDENTIFIER_NODE)
-               return 0;
-           }
-
-         return (args == NULL_TREE);
-       }
-    }
-
   return 0;
 }
 
@@ -5904,36 +6688,6 @@ rs6000_set_default_type_attributes (type)
   return;
 }
 
-/* Return a dll import reference corresponding to a call's SYMBOL_REF */
-struct rtx_def *
-rs6000_dll_import_ref (call_ref)
-     rtx call_ref;
-{
-  const char *call_name;
-  int len;
-  char *p;
-  rtx reg1, reg2;
-  tree node;
-
-  if (GET_CODE (call_ref) != SYMBOL_REF)
-    abort ();
-
-  call_name = XSTR (call_ref, 0);
-  len = sizeof ("__imp_") + strlen (call_name);
-  p = alloca (len);
-  reg2 = gen_reg_rtx (Pmode);
-
-  strcpy (p, "__imp_");
-  strcat (p, call_name);
-  node = get_identifier (p);
-
-  reg1 = force_reg (Pmode, gen_rtx_SYMBOL_REF (VOIDmode,
-                                              IDENTIFIER_POINTER (node)));
-  emit_move_insn (reg2, gen_rtx_MEM (Pmode, reg1));
-
-  return reg2;
-}
-
 /* Return a reference suitable for calling a function with the
    longcall attribute.  */
 struct rtx_def *
@@ -6039,7 +6793,7 @@ rs6000_select_section (decl, reloc)
 /* If we are referencing a function that is static or is known to be
    in this file, make the SYMBOL_REF special.  We can use this to indicate
    that we can branch to this function without emitting a no-op after the
-   call.  For real AIX and NT calling sequences, we also replace the
+   call.  For real AIX calling sequences, we also replace the
    function name with the real name (1 or 2 leading .'s), rather than
    the function descriptor name.  This saves a lot of overriding code
    to read the prefixes.  */
@@ -6055,7 +6809,7 @@ rs6000_encode_section_info (decl)
           && ! DECL_WEAK (decl))
        SYMBOL_REF_FLAG (sym_ref) = 1;
 
-      if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+      if (DEFAULT_ABI == ABI_AIX)
        {
          size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
          size_t len2 = strlen (XSTR (sym_ref, 0));
@@ -6173,4 +6927,8 @@ rs6000_add_gc_roots ()
 {
   ggc_add_rtx_root (&rs6000_compare_op0, 1);
   ggc_add_rtx_root (&rs6000_compare_op1, 1);
+
+  toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
+  ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table), 
+               toc_hash_mark_table);
 }
index a58f66f..e55ae93 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler, for IBM RS/6000.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
-   Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000 Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 This file is part of GNU CC.
@@ -22,13 +22,18 @@ Boston, MA 02111-1307, USA.  */
 
 
 /* Note that some other tm.h files include this one and then override
-   many of the definitions that relate to assembler syntax.  */
+   many of the definitions.  */
 
+/* Definitions for the object file format.  These are set at
+   compile-time.  */
 
-/* Names to predefine in the preprocessor for this target machine.  */
+#define OBJECT_XCOFF 1
+#define OBJECT_ELF 2
+#define OBJECT_PEF 3
 
-#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \
--Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)"
+#define TARGET_ELF (TARGET_OBJECT_FORMAT == OBJECT_ELF)
+#define TARGET_AIX (TARGET_OBJECT_FORMAT == OBJECT_XCOFF)
+#define TARGET_MACOS (TARGET_OBJECT_FORMAT == OBJECT_PEF)
 
 /* Print subsidiary information on the compiler version in use.  */
 #define TARGET_VERSION ;
@@ -38,16 +43,6 @@ Boston, MA 02111-1307, USA.  */
 #define TARGET_CPU_DEFAULT ((char *)0)
 #endif
 
-/* Tell the assembler to assume that all undefined names are external.
-
-   Don't do this until the fixed IBM assembler is more generally available.
-   When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL,
-   ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no
-   longer be needed.  Also, the extern declaration of mcount in ASM_FILE_START
-   will no longer be needed.  */
-
-/* #define ASM_SPEC "-u %(asm_cpu)" */
-
 /* Define appropriate architecture macros for preprocessor depending on
    target switches.  */
 
@@ -89,25 +84,7 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=823: -D_ARCH_PPC} \
 %{mcpu=860: -D_ARCH_PPC}"
 
-#ifndef CPP_DEFAULT_SPEC
 #define CPP_DEFAULT_SPEC "-D_ARCH_PWR"
-#endif
-
-#ifndef CPP_SYSV_SPEC
-#define CPP_SYSV_SPEC ""
-#endif
-
-#ifndef CPP_ENDIAN_SPEC
-#define CPP_ENDIAN_SPEC ""
-#endif
-
-#ifndef CPP_ENDIAN_DEFAULT_SPEC
-#define CPP_ENDIAN_DEFAULT_SPEC ""
-#endif
-
-#ifndef CPP_SYSV_DEFAULT_SPEC
-#define CPP_SYSV_DEFAULT_SPEC ""
-#endif
 
 /* Common ASM definitions used by ASM_SPEC among the various targets
    for handling -mcpu=xxx switches.  */
@@ -145,9 +122,7 @@ Boston, MA 02111-1307, USA.  */
 %{mcpu=823: -mppc} \
 %{mcpu=860: -mppc}"
 
-#ifndef ASM_DEFAULT_SPEC
 #define ASM_DEFAULT_SPEC ""
-#endif
 
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
@@ -159,65 +134,18 @@ Boston, MA 02111-1307, USA.  */
 
    Do not define this macro if it does not need to do anything.  */
 
-#ifndef SUBTARGET_EXTRA_SPECS
 #define SUBTARGET_EXTRA_SPECS
-#endif
 
 #define EXTRA_SPECS                                                    \
   { "cpp_cpu",                 CPP_CPU_SPEC },                         \
   { "cpp_default",             CPP_DEFAULT_SPEC },                     \
-  { "cpp_sysv",                        CPP_SYSV_SPEC },                        \
-  { "cpp_sysv_default",                CPP_SYSV_DEFAULT_SPEC },                \
-  { "cpp_endian_default",      CPP_ENDIAN_DEFAULT_SPEC },              \
-  { "cpp_endian",              CPP_ENDIAN_SPEC },                      \
   { "asm_cpu",                 ASM_CPU_SPEC },                         \
   { "asm_default",             ASM_DEFAULT_SPEC },                     \
-  { "link_syscalls",           LINK_SYSCALLS_SPEC },                   \
-  { "link_libg",               LINK_LIBG_SPEC },                       \
   SUBTARGET_EXTRA_SPECS
 
-/* Default location of syscalls.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
-#else
-#define LINK_SYSCALLS_SPEC ""
-#endif
-
-/* Default location of libg.exp under AIX */
-#ifndef CROSS_COMPILE
-#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
-#else
-#define LINK_LIBG_SPEC ""
-#endif
-
-/* Define the options for the binder: Start text at 512, align all segments
-   to 512 bytes, and warn if there is text relocation.
-
-   The -bhalt:4 option supposedly changes the level at which ld will abort,
-   but it also suppresses warnings about multiply defined symbols and is
-   used by the AIX cc command.  So we use it here.
-
-   -bnodelcsect undoes a poor choice of default relating to multiply-defined
-   csects.  See AIX documentation for more information about this.
-
-   -bM:SRE tells the linker that the output file is Shared REusable.  Note
-   that to actually build a shared library you will also need to specify an
-   export list with the -Wl,-bE option.  */
-
-#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\
-   %{static:-bnso %(link_syscalls) } \
-   %{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
-
-/* Profiled library versions are used by linking with special directories.  */
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-   %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
-
 /* gcc must do the search itself to find libgcc.a, not use -l.  */
 #define LIBGCC_SPEC "libgcc.a%s"
 
-/* Don't turn -B into -L if the argument specifies a relative file name.  */
-#define RELATIVE_PREFIX_NOT_LINKDIR
-
 /* Architecture type.  */
 
 extern int target_flags;
@@ -280,12 +208,14 @@ extern int target_flags;
 /* Disable fused multiply/add operations */
 #define MASK_NO_FUSED_MADD     0x00020000
 
+/* Nonzero if we need to schedule the prolog and epilog.  */
+#define MASK_SCHED_PROLOG      0x00040000
+
 #define TARGET_POWER           (target_flags & MASK_POWER)
 #define TARGET_POWER2          (target_flags & MASK_POWER2)
 #define TARGET_POWERPC         (target_flags & MASK_POWERPC)
 #define TARGET_PPC_GPOPT       (target_flags & MASK_PPC_GPOPT)
 #define TARGET_PPC_GFXOPT      (target_flags & MASK_PPC_GFXOPT)
-#define TARGET_POWERPC64       (target_flags & MASK_POWERPC64)
 #define TARGET_NEW_MNEMONICS   (target_flags & MASK_NEW_MNEMONICS)
 #define TARGET_NO_FP_IN_TOC    (target_flags & MASK_NO_FP_IN_TOC)
 #define TARGET_NO_SUM_IN_TOC   (target_flags & MASK_NO_SUM_IN_TOC)
@@ -298,6 +228,7 @@ extern int target_flags;
 #define TARGET_STRING_SET      (target_flags & MASK_STRING_SET)
 #define TARGET_NO_UPDATE       (target_flags & MASK_NO_UPDATE)
 #define TARGET_NO_FUSED_MADD   (target_flags & MASK_NO_FUSED_MADD)
+#define TARGET_SCHED_PROLOG    (target_flags & MASK_SCHED_PROLOG)
 
 #define TARGET_32BIT           (! TARGET_64BIT)
 #define TARGET_HARD_FLOAT      (! TARGET_SOFT_FLOAT)
@@ -306,48 +237,16 @@ extern int target_flags;
 
 #ifdef IN_LIBGCC2
 /* For libgcc2 we make sure this is a compile time constant */
-#undef TARGET_POWERPC64
 #ifdef __64BIT__
 #define TARGET_POWERPC64       1
 #else
 #define TARGET_POWERPC64       0
 #endif
-#endif
-
-/* Pseudo target to indicate whether the object format is ELF
-   (to get around not having conditional compilation in the md file)  */
-#ifndef        TARGET_ELF
-#define        TARGET_ELF              0
-#endif
-
-/* If this isn't V.4, don't support -mno-toc.  */
-#ifndef TARGET_NO_TOC
-#define TARGET_NO_TOC          0
-#define        TARGET_TOC              1
-#endif
-
-/* Pseudo target to say whether this is Windows NT */
-#ifndef        TARGET_WINDOWS_NT
-#define        TARGET_WINDOWS_NT 0
-#endif
-
-/* Pseudo target to say whether this is MAC */
-#ifndef        TARGET_MACOS
-#define        TARGET_MACOS 0
-#endif
-
-/* Pseudo target to say whether this is AIX */
-#ifndef TARGET_AIX
-#if (TARGET_ELF || TARGET_WINDOWS_NT || TARGET_MACOS)
-#define TARGET_AIX 0
 #else
-#define TARGET_AIX 1
-#endif
+#define TARGET_POWERPC64       (target_flags & MASK_POWERPC64)
 #endif
 
-#ifndef TARGET_XL_CALL
 #define TARGET_XL_CALL 0
-#endif
 
 /* Run-time compilation parameters selecting different hardware subsets.
 
@@ -357,55 +256,95 @@ extern int target_flags;
    where VALUE is the bits to set or minus the bits to clear.
    An empty string NAME is used to identify the default VALUE.  */
 
-/* This is meant to be redefined in the host dependent files */
-#ifndef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES
-#endif
-
 #define TARGET_SWITCHES                                                        \
- {{"power",            MASK_POWER  | MASK_MULTIPLE | MASK_STRING},     \
+ {{"power",            MASK_POWER  | MASK_MULTIPLE | MASK_STRING,      \
+                       "Use POWER instruction set"},                   \
   {"power2",           (MASK_POWER | MASK_MULTIPLE | MASK_STRING       \
-                        | MASK_POWER2)},                               \
-  {"no-power2",                - MASK_POWER2},                                 \
+                        | MASK_POWER2),                                \
+                       "Use POWER2 instruction set"},                  \
+  {"no-power2",                - MASK_POWER2,                                  \
+                       "Do not use POWER2 instruction set"},           \
   {"no-power",         - (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE     \
-                          | MASK_STRING)},                             \
-  {"powerpc",          MASK_POWERPC},                                  \
+                          | MASK_STRING),                              \
+                       "Do not use POWER instruction set"},            \
+  {"powerpc",          MASK_POWERPC,                                   \
+                       "Use PowerPC instruction set"},                 \
   {"no-powerpc",       - (MASK_POWERPC | MASK_PPC_GPOPT                \
-                          | MASK_PPC_GFXOPT | MASK_POWERPC64)},        \
-  {"powerpc-gpopt",    MASK_POWERPC | MASK_PPC_GPOPT},                 \
-  {"no-powerpc-gpopt", - MASK_PPC_GPOPT},                              \
-  {"powerpc-gfxopt",   MASK_POWERPC | MASK_PPC_GFXOPT},                \
-  {"no-powerpc-gfxopt",        - MASK_PPC_GFXOPT},                             \
-  {"powerpc64",                MASK_POWERPC64},                                \
-  {"no-powerpc64",     - MASK_POWERPC64},                              \
-  {"new-mnemonics",    MASK_NEW_MNEMONICS},                            \
-  {"old-mnemonics",    -MASK_NEW_MNEMONICS},                           \
+                          | MASK_PPC_GFXOPT | MASK_POWERPC64),         \
+                       "Do not use PowerPC instruction set"},          \
+  {"powerpc-gpopt",    MASK_POWERPC | MASK_PPC_GPOPT,                  \
+                       "Use PowerPC General Purpose group optional instructions"},\
+  {"no-powerpc-gpopt", - MASK_PPC_GPOPT,                               \
+                       "Don't use PowerPC General Purpose group optional instructions"},\
+  {"powerpc-gfxopt",   MASK_POWERPC | MASK_PPC_GFXOPT,                 \
+                       "Use PowerPC Graphics group optional instructions"},\
+  {"no-powerpc-gfxopt",        - MASK_PPC_GFXOPT,                              \
+                       "Don't use PowerPC Graphics group optional instructions"},\
+  {"powerpc64",                MASK_POWERPC64,                                 \
+                       "Use PowerPC-64 instruction set"},              \
+  {"no-powerpc64",     - MASK_POWERPC64,                               \
+                       "Don't use PowerPC-64 instruction set"},        \
+  {"new-mnemonics",    MASK_NEW_MNEMONICS,                             \
+                       "Use new mnemonics for PowerPC architecture"},  \
+  {"old-mnemonics",    -MASK_NEW_MNEMONICS,                            \
+                       "Use old mnemonics for PowerPC architecture"},  \
   {"full-toc",         - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC       \
-                          | MASK_MINIMAL_TOC)},                        \
-  {"fp-in-toc",                - MASK_NO_FP_IN_TOC},                           \
-  {"no-fp-in-toc",     MASK_NO_FP_IN_TOC},                             \
-  {"sum-in-toc",       - MASK_NO_SUM_IN_TOC},                          \
-  {"no-sum-in-toc",    MASK_NO_SUM_IN_TOC},                            \
-  {"minimal-toc",      MASK_MINIMAL_TOC},                              \
-  {"minimal-toc",      - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)},    \
-  {"no-minimal-toc",   - MASK_MINIMAL_TOC},                            \
-  {"hard-float",       - MASK_SOFT_FLOAT},                             \
-  {"soft-float",       MASK_SOFT_FLOAT},                               \
-  {"multiple",         MASK_MULTIPLE | MASK_MULTIPLE_SET},             \
-  {"no-multiple",      - MASK_MULTIPLE},                               \
-  {"no-multiple",      MASK_MULTIPLE_SET},                             \
-  {"string",           MASK_STRING | MASK_STRING_SET},                 \
-  {"no-string",                - MASK_STRING},                                 \
-  {"no-string",                MASK_STRING_SET},                               \
-  {"update",           - MASK_NO_UPDATE},                              \
-  {"no-update",                MASK_NO_UPDATE},                                \
-  {"fused-madd",       - MASK_NO_FUSED_MADD},                          \
-  {"no-fused-madd",    MASK_NO_FUSED_MADD},                            \
+                          | MASK_MINIMAL_TOC),                         \
+                       "Put everything in the regular TOC"},           \
+  {"fp-in-toc",                - MASK_NO_FP_IN_TOC,                            \
+                       "Place floating point constants in TOC"},       \
+  {"no-fp-in-toc",     MASK_NO_FP_IN_TOC,                              \
+                       "Don't place floating point constants in TOC"}, \
+  {"sum-in-toc",       - MASK_NO_SUM_IN_TOC,                           \
+                       "Place symbol+offset constants in TOC"},        \
+  {"no-sum-in-toc",    MASK_NO_SUM_IN_TOC,                             \
+                       "Don't place symbol+offset constants in TOC"},  \
+  {"minimal-toc",      MASK_MINIMAL_TOC,                               \
+                       "Use only one TOC entry per procedure"},        \
+  {"minimal-toc",      - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC),     \
+                       ""},                            \
+  {"no-minimal-toc",   - MASK_MINIMAL_TOC,                             \
+                       "Place variable addresses in the regular TOC"}, \
+  {"hard-float",       - MASK_SOFT_FLOAT,                              \
+                       "Use hardware fp"},                             \
+  {"soft-float",       MASK_SOFT_FLOAT,                                \
+                       "Do not use hardware fp"},                      \
+  {"multiple",         MASK_MULTIPLE | MASK_MULTIPLE_SET,              \
+                       "Generate load/store multiple instructions"},   \
+  {"no-multiple",      - MASK_MULTIPLE,                                \
+                       "Do not generate load/store multiple instructions"},\
+  {"no-multiple",      MASK_MULTIPLE_SET,                              \
+                       ""},\
+  {"string",           MASK_STRING | MASK_STRING_SET,                  \
+                       "Generate string instructions for block moves"},\
+  {"no-string",                - MASK_STRING,                                  \
+                       "Do not generate string instructions for block moves"},\
+  {"no-string",                MASK_STRING_SET,                                \
+                       ""},\
+  {"update",           - MASK_NO_UPDATE,                               \
+                       "Generate load/store with update instructions"},\
+  {"no-update",                MASK_NO_UPDATE,                                 \
+                       "Do not generate load/store with update instructions"},\
+  {"fused-madd",       - MASK_NO_FUSED_MADD,                           \
+                       "Generate fused multiply/add instructions"},    \
+  {"no-fused-madd",    MASK_NO_FUSED_MADD,                             \
+                       "Don't generate fused multiply/add instructions"},\
+  {"sched-prolog",      MASK_SCHED_PROLOG,                              \
+                       ""},                                            \
+  {"no-sched-prolog",   -MASK_SCHED_PROLOG,                             \
+                       "Don't schedule the start and end of the procedure"},\
+  {"sched-epilog",      MASK_SCHED_PROLOG,                              \
+                       ""},                                            \
+  {"no-sched-epilog",   -MASK_SCHED_PROLOG,                             \
+                       ""},                                            \
   SUBTARGET_SWITCHES                                                   \
-  {"",                 TARGET_DEFAULT | SUBTARGET_DEFAULT}}
+  {"",                 TARGET_DEFAULT | MASK_SCHED_PROLOG,             \
+                       ""}}
 
 #define TARGET_DEFAULT (MASK_POWER | MASK_MULTIPLE | MASK_STRING)
-#define SUBTARGET_DEFAULT 0
+
+/* This is meant to be redefined in the host dependent files */
+#define SUBTARGET_SWITCHES
 
 /* Processor type.  Order must match cpu attribute in MD file.  */
 enum processor_type
@@ -441,7 +380,7 @@ extern enum processor_type rs6000_cpu;
 
 /* Specify the dialect of assembler to use.  New mnemonics is dialect one
    and the old mnemonics are dialect zero.  */
-#define ASSEMBLER_DIALECT TARGET_NEW_MNEMONICS ? 1 : 0
+#define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0)
 
 /* This macro is similar to `TARGET_SWITCHES' but defines names of
    command options that have values.  Its definition is an
@@ -461,17 +400,14 @@ extern enum processor_type rs6000_cpu;
        #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } }  */
 
 /* This is meant to be overridden in target specific files.  */
-#ifndef SUBTARGET_OPTIONS
 #define        SUBTARGET_OPTIONS
-#endif
 
-#define TARGET_OPTIONS                         \
-{                                              \
-   {"cpu=",  &rs6000_select[1].string},                \
-   {"tune=", &rs6000_select[2].string},                \
-   {"debug-", &rs6000_debug_name},             \
-   {"debug=", &rs6000_debug_name},             \
-   SUBTARGET_OPTIONS                           \
+#define TARGET_OPTIONS                                                 \
+{                                                                      \
+   {"cpu=",  &rs6000_select[1].string, "Use features of and schedule code for given CPU" },\
+   {"tune=", &rs6000_select[2].string, "Schedule code for given CPU" },        \
+   {"debug=", &rs6000_debug_name, "Enable debug output" },             \
+   SUBTARGET_OPTIONS                                                   \
 }
 
 /* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
@@ -685,9 +621,9 @@ extern int rs6000_debug_arg;                /* debug argument handling */
    many times greater than aligned accesses, for example if they are
    emulated in a trap handler.  */
 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN)                     \
-   ((((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode)        \
-     && (ALIGN) < 4) ? 1 : 0)
-
+   ((STRICT_ALIGNMENT                                          \
+     || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \
+         && (ALIGN) < 4)) ? 1 : 0)
 \f
 /* Standard register usage.  */
 
@@ -722,10 +658,6 @@ extern int rs6000_debug_arg;               /* debug argument handling */
 
    On System V implementations, r13 is fixed and not available for use.  */
 
-#ifndef FIXED_R13
-#define FIXED_R13 0
-#endif
-
 #define FIXED_REGISTERS  \
   {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -747,6 +679,15 @@ extern int rs6000_debug_arg;               /* debug argument handling */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1}
 
+#define MQ_REGNO     64
+#define CR0_REGNO    68
+#define CR1_REGNO    69
+#define CR2_REGNO    70
+#define CR3_REGNO    71
+#define CR4_REGNO    72
+#define MAX_CR_REGNO 75
+#define XER_REGNO    76
+
 /* List the order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.
 
@@ -768,7 +709,7 @@ extern int rs6000_debug_arg;                /* debug argument handling */
        mq              (not saved; best to use it if we can)
        ctr             (not saved; when we have the choice ctr is better)
        lr              (saved)
-        cr5, r1, r2, ap, fpmem (fixed)  */
+        cr5, r1, r2, ap, xer (fixed)  */
 
 #define REG_ALLOC_ORDER                                        \
   {32,                                                         \
@@ -791,18 +732,15 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 /* True if register is a condition register.  */
 #define CR_REGNO_P(N) ((N) >= 68 && (N) <= 75)
 
-/* True if register is condition register 0.  */
-#define CR0_REGNO_P(N) ((N) == 68)
-
 /* True if register is a condition register, but not cr0.  */
 #define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75)
 
 /* True if register is an integer register.  */
-#define INT_REGNO_P(N) ((N) <= 31 || (N) == 67)
+#define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM)
 
 /* True if register is the temporary memory location used for int/float
    conversion.  */
-#define FPMEM_REGNO_P(N) ((N) == FPMEM_REGNUM)
+#define XER_REGNO_P(N) ((N) == XER_REGNO)
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
    to hold something of mode MODE.
@@ -813,7 +751,7 @@ extern int rs6000_debug_arg;                /* debug argument handling */
    PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
 
 #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
-  (FP_REGNO_P (REGNO) || FPMEM_REGNO_P (REGNO)                         \
+  (FP_REGNO_P (REGNO)                                                  \
    ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
@@ -829,7 +767,7 @@ extern int rs6000_debug_arg;                /* debug argument handling */
     || (GET_MODE_CLASS (MODE) == MODE_INT                              \
        && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD))                  \
    : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
-   : FPMEM_REGNO_P (REGNO) ? ((MODE) == DImode || (MODE) == DFmode)    \
+   : XER_REGNO_P (REGNO) ? (MODE) == PSImode                           \
    : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT                \
                              && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
    : 1)
@@ -949,11 +887,11 @@ extern int rs6000_debug_arg;              /* debug argument handling */
 /* Place to put static chain when calling a function that requires it.  */
 #define STATIC_CHAIN_REGNUM 11
 
-/* count register number for special purposes */
-#define COUNT_REGISTER_REGNUM 66
+/* Link register number. */
+#define LINK_REGISTER_REGNUM 65
 
-/* Special register that represents memory, used for float/int conversions.  */
-#define FPMEM_REGNUM 76
+/* Count register number. */
+#define COUNT_REGISTER_REGNUM 66
 
 /* Place that structure value return address is placed.
 
@@ -1013,8 +951,7 @@ enum reg_class
   CR0_REGS,
   CR_REGS,
   NON_FLOAT_REGS,
-  FPMEM_REGS,
-  FLOAT_OR_FPMEM_REGS,
+  XER_REGS,
   ALL_REGS,
   LIM_REG_CLASSES
 };
@@ -1039,8 +976,7 @@ enum reg_class
   "CR0_REGS",                                                          \
   "CR_REGS",                                                           \
   "NON_FLOAT_REGS",                                                    \
-  "FPMEM_REGS",                                                                \
-  "FLOAT_OR_FPMEM_REGS",                                               \
+  "XER_REGS",                                                          \
   "ALL_REGS"                                                           \
 }
 
@@ -1064,8 +1000,7 @@ enum reg_class
   { 0x00000000, 0x00000000, 0x00000010 },      /* CR0_REGS */          \
   { 0x00000000, 0x00000000, 0x00000ff0 },      /* CR_REGS */           \
   { 0xffffffff, 0x00000000, 0x0000ffff },      /* NON_FLOAT_REGS */    \
-  { 0x00000000, 0x00000000, 0x00010000 },      /* FPMEM_REGS */        \
-  { 0x00000000, 0xffffffff, 0x00010000 },      /* FLOAT_OR_FPMEM_REGS */ \
+  { 0x00000000, 0x00000000, 0x00010000 },      /* XER_REGS */          \
   { 0xffffffff, 0xffffffff, 0x0001ffff }       /* ALL_REGS */          \
 }
 
@@ -1084,7 +1019,7 @@ enum reg_class
   : (REGNO) == 65 ? LINK_REGS          \
   : (REGNO) == 66 ? CTR_REGS           \
   : (REGNO) == 67 ? BASE_REGS          \
-  : (REGNO) == 76 ? FPMEM_REGS         \
+  : (REGNO) == 76 ? XER_REGS           \
   : NO_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
@@ -1102,7 +1037,7 @@ enum reg_class
    : (C) == 'l' ? LINK_REGS    \
    : (C) == 'x' ? CR0_REGS     \
    : (C) == 'y' ? CR_REGS      \
-   : (C) == 'z' ? FPMEM_REGS   \
+   : (C) == 'z' ? XER_REGS     \
    : NO_REGS)
 
 /* The letters I, J, K, L, M, N, and P in a register constraint string
@@ -1122,7 +1057,7 @@ enum reg_class
 
 #define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
    ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000        \
-   : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0      \
+   : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000u)) == 0     \
    : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0          \
    : (C) == 'L' ? (((VALUE) & 0xffff) == 0                             \
                   && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0))      \
@@ -1195,15 +1130,14 @@ enum reg_class
    On RS/6000, this is the size of MODE in words,
    except in the FP regs, where a single reg is enough for two words.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)                                   \
- (((CLASS) == FLOAT_REGS || (CLASS) == FPMEM_REGS                      \
-   || (CLASS) == FLOAT_OR_FPMEM_REGS)                                  \
+ (((CLASS) == FLOAT_REGS)                                              \
   ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 /* If defined, gives a class of registers that cannot be used as the
    operand of a SUBREG that changes the size of the object.  */
 
-#define CLASS_CANNOT_CHANGE_SIZE       FLOAT_OR_FPMEM_REGS
+#define CLASS_CANNOT_CHANGE_SIZE      FLOAT_REGS
 \f
 /* Stack layout; function entry, exit and calling.  */
 
@@ -1213,19 +1147,11 @@ enum rs6000_abi {
   ABI_AIX,                     /* IBM's AIX */
   ABI_AIX_NODESC,              /* AIX calling sequence minus function descriptors */
   ABI_V4,                      /* System V.4/eabi */
-  ABI_NT,                      /* Windows/NT */
   ABI_SOLARIS                  /* Solaris */
 };
 
 extern enum rs6000_abi rs6000_current_abi;     /* available for use by subtarget */
 
-/* Default ABI to compile code for */
-#ifndef DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
-/* The prefix to add to user-visible assembler symbols. */
-#define USER_LABEL_PREFIX "."
-#endif
-
 /* Structure used to define the rs6000 stack */
 typedef struct rs6000_stack {
   int first_gp_reg_save;       /* first callee saved GP register used */
@@ -1235,9 +1161,6 @@ typedef struct rs6000_stack {
   int toc_save_p;              /* true if the TOC needs to be saved */
   int push_p;                  /* true if we need to allocate stack space */
   int calls_p;                 /* true if the function makes any calls */
-  int main_p;                  /* true if this is main */
-  int main_save_p;             /* true if this is main and we need to save args */
-  int fpmem_p;                 /* true if float/int conversion temp needed */
   enum rs6000_abi abi;         /* which ABI to use */
   int gp_save_offset;          /* offset to save GP regs from initial SP */
   int fp_save_offset;          /* offset to save FP regs from initial SP */
@@ -1245,20 +1168,16 @@ typedef struct rs6000_stack {
   int cr_save_offset;          /* offset to save CR from initial SP */
   int toc_save_offset;         /* offset to save the TOC pointer */
   int varargs_save_offset;     /* offset to save the varargs registers */
-  int main_save_offset;                /* offset to save main's args */
-  int fpmem_offset;            /* offset for float/int conversion temp */
   int reg_size;                        /* register size (4 or 8) */
   int varargs_size;            /* size to hold V.4 args passed in regs */
   int vars_size;               /* variable save area size */
   int parm_size;               /* outgoing parameter size */
-  int main_size;               /* size to hold saving main's args */
   int save_size;               /* save area size */
   int fixed_size;              /* fixed size of stack frame */
   int gp_size;                 /* size of saved GP registers */
   int fp_size;                 /* size of saved FP registers */
   int cr_size;                 /* size to hold CR if not in save_size */
   int lr_size;                 /* size to hold LR if not in save_size */
-  int fpmem_size;              /* size to hold float/int conversion */
   int toc_size;                        /* size to hold TOC if not in save_size */
   int total_size;              /* total bytes allocated for stack */
 } rs6000_stack_t;
@@ -1277,21 +1196,21 @@ typedef struct rs6000_stack {
 /* #define FRAME_GROWS_DOWNWARD */
 
 /* Size of the outgoing register save area */
-#define RS6000_REG_SAVE (TARGET_32BIT ? 32 : 64)
+#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX                       \
+                         || DEFAULT_ABI == ABI_AIX_NODESC)             \
+                        ? (TARGET_64BIT ? 64 : 32)                     \
+                        : 0)
 
 /* Size of the fixed area on the stack */
-#define RS6000_SAVE_AREA (TARGET_32BIT ? 24 : 48)
+#define RS6000_SAVE_AREA \
+  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) ? 24 : 8)        \
+   << (TARGET_64BIT ? 1 : 0))
 
 /* MEM representing address to save the TOC register */
 #define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \
                                     plus_constant (stack_pointer_rtx, \
                                                    (TARGET_32BIT ? 20 : 40)))
 
-/* Offset & size for fpmem stack locations used for converting between
-   float and integral types.  */
-extern int rs6000_fpmem_offset;
-extern int rs6000_fpmem_size;
-
 /* Size of the V.4 varargs area if needed */
 #define RS6000_VARARGS_AREA 0
 
@@ -1420,7 +1339,9 @@ extern int rs6000_sysv_varargs_p;
 #define FP_ARG_MIN_REG 33
 #define        FP_ARG_AIX_MAX_REG 45
 #define        FP_ARG_V4_MAX_REG  40
-#define FP_ARG_MAX_REG FP_ARG_AIX_MAX_REG
+#define        FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX                         \
+                        || DEFAULT_ABI == ABI_AIX_NODESC)              \
+                       ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
 #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
 
 /* Return registers */
@@ -1429,14 +1350,11 @@ extern int rs6000_sysv_varargs_p;
 
 /* Flags for the call/call_value rtl operations set up by function_arg */
 #define CALL_NORMAL            0x00000000      /* no special processing */
-#define CALL_NT_DLLIMPORT      0x00000001      /* NT, this is a DLL import call */
+/* Bits in 0x00000001 are unused.  */
 #define CALL_V4_CLEAR_FP_ARGS  0x00000002      /* V.4, no FP args passed */
 #define CALL_V4_SET_FP_ARGS    0x00000004      /* V.4, FP args were passed */
 #define CALL_LONG              0x00000008      /* always call indirect */
 
-/* Define cutoff for using external functions to save floating point */
-#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
-
 /* 1 if N is a possible register number for a function value
    as seen by the caller.
 
@@ -1561,8 +1479,7 @@ typedef struct rs6000_args
    the argument, `downward' to pad below, or `none' to inhibit
    padding.  */
 
-#define FUNCTION_ARG_PADDING(MODE, TYPE) \
-  (enum direction) function_arg_padding (MODE, TYPE)
+#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE)
 
 /* If defined, a C expression that gives the alignment boundary, in bits,
    of an argument with the specified mode and type.  If it is not defined,
@@ -1635,40 +1552,6 @@ typedef struct rs6000_args
    before returning.  */
 
 #define FUNCTION_EPILOGUE(FILE, SIZE) output_epilog (FILE, SIZE)
-
-/* A C compound statement that outputs the assembler code for a thunk function,
-   used to implement C++ virtual function calls with multiple inheritance.  The
-   thunk acts as a wrapper around a virtual function, adjusting the implicit
-   object parameter before handing control off to the real function.
-
-   First, emit code to add the integer DELTA to the location that contains the
-   incoming first argument.  Assume that this argument contains a pointer, and
-   is the one used to pass the `this' pointer in C++.  This is the incoming
-   argument *before* the function prologue, e.g. `%o0' on a sparc.  The
-   addition must preserve the values of all other incoming arguments.
-
-   After the addition, emit code to jump to FUNCTION, which is a
-   `FUNCTION_DECL'.  This is a direct pure jump, not a call, and does not touch
-   the return address.  Hence returning from FUNCTION will return to whoever
-   called the current `thunk'.
-
-   The effect must be as if FUNCTION had been called directly with the adjusted
-   first argument.  This macro is responsible for emitting all of the code for
-   a thunk function; `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' are not
-   invoked.
-
-   The THUNK_FNDECL is redundant.  (DELTA and FUNCTION have already been
-   extracted from it.)  It might possibly be useful on some targets, but
-   probably not.
-
-   If you do not define this macro, the target-independent code in the C++
-   frontend will generate a less efficient heavyweight thunk that calls
-   FUNCTION instead of jumping to it.  The generic approach does not support
-   varargs.  */
-#if TARGET_ELF
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-  output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
-#endif
 \f
 /* TRAMPOLINE_TEMPLATE deleted */
 
@@ -1730,7 +1613,6 @@ typedef struct rs6000_args
    || DEFAULT_ABI == ABI_AIX_NODESC)   ? 8 :                           \
   (DEFAULT_ABI == ABI_V4                                               \
    || DEFAULT_ABI == ABI_SOLARIS)      ? (TARGET_32BIT ? 4 : 8) :      \
-  (DEFAULT_ABI == ABI_NT)              ? -4 :                          \
   (fatal ("RETURN_ADDRESS_OFFSET not supported"), 0))
 
 /* The current return address is in link register (65).  The return address
@@ -1738,7 +1620,7 @@ typedef struct rs6000_args
    frame pointer.  */
 #define RETURN_ADDR_RTX(count, frame)                  \
   ((count == -1)                                       \
-   ? gen_rtx_REG (Pmode, 65)                           \
+   ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)         \
    : gen_rtx_MEM (Pmode,                               \
                  memory_address                        \
                  (Pmode,                               \
@@ -1906,18 +1788,16 @@ typedef struct rs6000_args
    adjacent memory cells are accessed by adding word-sized offsets
    during assembly output.  */
 
-#define LEGITIMATE_CONSTANT_POOL_BASE_P(X)                             \
-  (TARGET_TOC && GET_CODE (X) == SYMBOL_REF                            \
-   && CONSTANT_POOL_ADDRESS_P (X)                                      \
-   && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X)))
+#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X))
+
+#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
 
-/* AIX64 guaranteed to have 64 bit TOC alignment.  */
 #define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X)                          \
-  (LEGITIMATE_CONSTANT_POOL_BASE_P (X)                                 \
-   || (TARGET_TOC                                                      \
-       && GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS      \
-       && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT                        \
-       && LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0))))
+  (TARGET_TOC                                                          \
+  && GET_CODE (X) == PLUS                                              \
+  && GET_CODE (XEXP (X, 0)) == REG                                     \
+  && (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER)       \
+  && CONSTANT_POOL_EXPR_P (XEXP (X, 1)))
 
 #define LEGITIMATE_SMALL_DATA_P(MODE, X)                               \
   ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)               \
@@ -2012,43 +1892,13 @@ typedef struct rs6000_args
    Then check for the sum of a register and something not constant, try to
    load the other things into a register and return the sum.  */
 
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)                            \
-{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG            \
-    && GET_CODE (XEXP (X, 1)) == CONST_INT                             \
-    && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) + 0x8000) >= 0x10000) \
-    { HOST_WIDE_INT high_int, low_int;                                 \
-      rtx sum;                                                         \
-      high_int = INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff);    \
-      low_int = INTVAL (XEXP (X, 1)) & 0xffff;                         \
-      if (low_int & 0x8000)                                            \
-       high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;     \
-      sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (X, 0),           \
-                                        GEN_INT (high_int)), 0);       \
-      (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));              \
-      goto WIN;                                                                \
-    }                                                                  \
-  else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG       \
-          && GET_CODE (XEXP (X, 1)) != CONST_INT                       \
-          && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
-          && (TARGET_POWERPC64 || (MODE) != DImode)                    \
-          && (MODE) != TImode)                                         \
-    {                                                                  \
-      (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0),                          \
-                         force_reg (Pmode, force_operand (XEXP (X, 1), 0))); \
-      goto WIN;                                                                \
-    }                                                                  \
-  else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC                 \
-          && !flag_pic                                                 \
-          && GET_CODE (X) != CONST_INT                                 \
-          && GET_CODE (X) != CONST_DOUBLE && CONSTANT_P (X)            \
-          && (TARGET_HARD_FLOAT || (MODE) != DFmode)                   \
-          && (MODE) != DImode && (MODE) != TImode)                     \
-    {                                                                  \
-      rtx reg = gen_reg_rtx (Pmode);                                   \
-      emit_insn (gen_elf_high (reg, (X)));                             \
-      (X) = gen_rtx_LO_SUM (Pmode, reg, (X));                          \
-      goto WIN;                                                                \
-    }                                                                  \
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)                    \
+{  rtx result = rs6000_legitimize_address (X, OLDX, MODE);     \
+   if (result != NULL_RTX)                                     \
+     {                                                         \
+       (X) = result;                                           \
+       goto WIN;                                               \
+     }                                                         \
 }
 
 /* Try a machine-dependent way of reloading an illegitimate address
@@ -2082,7 +1932,7 @@ do {                                                                    \
       HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                         \
       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;           \
       HOST_WIDE_INT high                                                \
-        = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;       \
+        = (((val - low) & 0xffffffffu) ^ 0x80000000u) - 0x80000000u;       \
                                                                         \
       /* Check for 32-bit overflow.  */                                 \
       if (high + low != val)                                            \
@@ -2101,6 +1951,13 @@ do {                                                                    \
                    OPNUM, TYPE);                                        \
       goto WIN;                                                         \
     }                                                                   \
+  else if (TARGET_TOC                                                  \
+          && CONSTANT_POOL_EXPR_P (X)                                  \
+          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X)))  \
+    {                                                                  \
+      (X) = create_TOC_reference (X);                                  \
+      goto WIN;                                                                \
+    }                                                                  \
 } while (0)
 
 /* Go to LABEL if ADDR (a legitimate address expression)
@@ -2136,6 +1993,8 @@ do {                                                                    \
 
 #define PIC_OFFSET_TABLE_REGNUM 30
 
+#define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2)
+
 /* Define this macro if the register defined by
    `PIC_OFFSET_TABLE_REGNUM' is clobbered by calls.  Do not define
    this macro if `PPIC_OFFSET_TABLE_REGNUM' is not defined. */
@@ -2172,12 +2031,9 @@ do {                                                                    \
 /* In rare cases, correct code generation requires extra machine
    dependent processing between the second jump optimization pass and
    delayed branch scheduling.  On those machines, define this macro
-   as a C statement to act on the code starting at INSN.
+   as a C statement to act on the code starting at INSN.  */
 
-   On the RS/6000, we use it to make sure the GOT_TOC register marker
-   that FINALIZE_PIC is supposed to remove actually got removed.  */
-
-#define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN)
+/* #define MACHINE_DEPENDENT_REORG(INSN) */
 
 \f
 /* Define this if some processing needs to be done immediately before
@@ -2232,38 +2088,6 @@ do {                                                                    \
 /* Define if loading short immediate values into registers sign extends.  */
 #define SHORT_IMMEDIATES_SIGN_EXTEND
 \f
-/* The RS/6000 uses the XCOFF format.  */
-
-#define XCOFF_DEBUGGING_INFO
-
-/* Define if the object format being used is COFF or a superset.  */
-#define OBJECT_FORMAT_COFF
-
-/* Define the magic numbers that we recognize as COFF.
-
-   AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects, but collect2.c
-   does not include files in the correct order to conditionally define
-   the symbolic name in this macro. 
-
-   The AIX linker accepts import/export files as object files,
-   so accept "#!" (0x2321) magic number.  */
-#define MY_ISCOFF(magic) \
-  ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \
-   || (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0x2321)
-
-/* This is the only version of nm that collect2 can work with.  */
-#define REAL_NM_FILE_NAME "/usr/ucb/nm"
-
-/* We don't have GAS for the RS/6000 yet, so don't write out special
-   .stabs in cc1plus.  */
-
-#define FASCIST_ASSEMBLER
-
-/* AIX does not have any init/fini or ctor/dtor sections, so create
-   static constructors and destructors as normal functions.  */
-/* #define ASM_OUTPUT_CONSTRUCTOR(file, name) */
-/* #define ASM_OUTPUT_DESTRUCTOR(file, name) */
-
 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
    is done just by pretending it is already truncated.  */
 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
@@ -2467,21 +2291,6 @@ extern int rs6000_trunc_used;
 #define RS6000_ITRUNC "__itrunc"
 #define RS6000_UITRUNC "__uitrunc"
 
-/* Prefix and suffix to use to saving floating point */
-#ifndef SAVE_FP_PREFIX
-#define        SAVE_FP_PREFIX "._savef"
-#define SAVE_FP_SUFFIX ""
-#endif
-
-/* Prefix and suffix to use to restoring floating point */
-#ifndef RESTORE_FP_PREFIX
-#define        RESTORE_FP_PREFIX "._restf"
-#define RESTORE_FP_SUFFIX ""
-#endif
-
-/* Function name to call to do profiling.  */
-#define RS6000_MCOUNT ".__mcount"
-
 \f
 /* Control the assembler format that we output.  */
 
@@ -2490,55 +2299,6 @@ extern int rs6000_trunc_used;
    the end of the line.  */
 #define ASM_COMMENT_START " #"
 
-/* Output at beginning of assembler file.
-
-   Initialize the section names for the RS/6000 at this point.
-
-   Specify filename, including full path, to assembler.
-
-   We want to go into the TOC section so at least one .toc will be emitted.
-   Also, in order to output proper .bs/.es pairs, we need at least one static
-   [RW] section emitted.
-
-   We then switch back to text to force the gcc2_compiled. label and the space
-   allocated after it (when profiling) into the text section.
-
-   Finally, declare mcount when profiling to make the assembler happy.  */
-
-#define ASM_FILE_START(FILE)                                   \
-{                                                              \
-  rs6000_gen_section_name (&xcoff_bss_section_name,            \
-                          main_input_filename, ".bss_");       \
-  rs6000_gen_section_name (&xcoff_private_data_section_name,   \
-                          main_input_filename, ".rw_");        \
-  rs6000_gen_section_name (&xcoff_read_only_section_name,      \
-                          main_input_filename, ".ro_");        \
-                                                               \
-  fprintf (FILE, "\t.file\t\"%s\"\n", main_input_filename);    \
-  if (TARGET_64BIT)                                            \
-    fputs ("\t.machine\t\"ppc64\"\n", FILE);                   \
-  toc_section ();                                              \
-  if (write_symbols != NO_DEBUG)                               \
-    private_data_section ();                                   \
-  text_section ();                                             \
-  if (profile_flag)                                            \
-    fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT);           \
-  rs6000_file_start (FILE, TARGET_CPU_DEFAULT);                        \
-}
-
-/* Output at end of assembler file.
-
-   On the RS/6000, referencing data should automatically pull in text.  */
-
-#define ASM_FILE_END(FILE)                                     \
-{                                                              \
-  text_section ();                                             \
-  fputs ("_section_.text:\n", FILE);                           \
-  data_section ();                                             \
-  fputs (TARGET_32BIT                                          \
-        ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", FILE); \
-}
-
 /* We define this to prevent the name mangler from putting dollar signs into
    function names.  */
 
@@ -2554,20 +2314,6 @@ extern int rs6000_trunc_used;
 
 #define TARGET_MEM_FUNCTIONS
 
-/* Define the extra sections we need.  We define three: one is the read-only
-   data section which is used for constants.  This is a csect whose name is
-   derived from the name of the input file.  The second is for initialized
-   global variables.  This is a csect whose name is that of the variable.
-   The third is the TOC.  */
-
-#define EXTRA_SECTIONS \
-   read_only_data, private_data, read_only_private_data, toc, bss
-
-/* Define the name of our readonly data section.  */
-
-#define READONLY_DATA_SECTION read_only_data_section
-
-
 /* Define the name of the section to use for the exception tables.
    TODO: test and see if we can use read_only_data_section, if so,
    remove this.  */
@@ -2585,118 +2331,9 @@ extern int rs6000_trunc_used;
       && ! DECL_WEAK (DECL))                           \
     SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
 
-/* Indicate that jump tables go in the text section.  */
-
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* Define the routines to implement these extra sections.
-   BIGGEST_ALIGNMENT is 64, so align the sections that much.  */
-
-#define EXTRA_SECTION_FUNCTIONS                                \
-                                                       \
-void                                                   \
-read_only_data_section ()                              \
-{                                                      \
-  if (in_section != read_only_data)                    \
-    {                                                  \
-      fprintf (asm_out_file, "\t.csect %s[RO],3\n",    \
-              xcoff_read_only_section_name);           \
-      in_section = read_only_data;                     \
-    }                                                  \
-}                                                      \
-                                                       \
-void                                                   \
-private_data_section ()                                        \
-{                                                      \
-  if (in_section != private_data)                      \
-    {                                                  \
-      fprintf (asm_out_file, "\t.csect %s[RW],3\n",    \
-              xcoff_private_data_section_name);        \
-      in_section = private_data;                       \
-    }                                                  \
-}                                                      \
-                                                       \
-void                                                   \
-read_only_private_data_section ()                      \
-{                                                      \
-  if (in_section != read_only_private_data)            \
-    {                                                  \
-      fprintf (asm_out_file, "\t.csect %s[RO],3\n",    \
-              xcoff_private_data_section_name);        \
-      in_section = read_only_private_data;             \
-    }                                                  \
-}                                                      \
-                                                       \
-void                                                   \
-toc_section ()                                         \
-{                                                      \
-  if (TARGET_MINIMAL_TOC)                              \
-    {                                                  \
-      /* toc_section is always called at least once from ASM_FILE_START, \
-        so this is guaranteed to always be defined once and only once   \
-        in each file.  */                                               \
-      if (! toc_initialized)                           \
-       {                                               \
-         fputs ("\t.toc\nLCTOC..0:\n", asm_out_file);  \
-         fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \
-         toc_initialized = 1;                          \
-       }                                               \
-                                                       \
-      if (in_section != toc)                           \
-       fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",    \
-                (TARGET_32BIT ? "" : ",3"));           \
-    }                                                  \
-  else                                                 \
-    {                                                  \
-      if (in_section != toc)                           \
-        fputs ("\t.toc\n", asm_out_file);              \
-    }                                                  \
-  in_section = toc;                                    \
-}
-
 /* Flag to say the TOC is initialized */
 extern int toc_initialized;
 
-/* This macro produces the initial definition of a function name.
-   On the RS/6000, we need to place an extra '.' in the function name and
-   output the function descriptor.
-
-   The csect for the function will have already been created by the
-   `text_section' call previously done.  We do have to go back to that
-   csect, however.
-
-   The third and fourth parameters to the .function pseudo-op (16 and 044)
-   are placeholders which no longer have any use.  */
-
-#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)              \
-{ if (TREE_PUBLIC (DECL))                                      \
-    {                                                          \
-      fputs ("\t.globl .", FILE);                              \
-      RS6000_OUTPUT_BASENAME (FILE, NAME);                     \
-      putc ('\n', FILE);                                       \
-    }                                                          \
-  else                                                         \
-    {                                                          \
-      fputs ("\t.lglobl .", FILE);                             \
-      RS6000_OUTPUT_BASENAME (FILE, NAME);                     \
-      putc ('\n', FILE);                                       \
-    }                                                          \
-  fputs ("\t.csect ", FILE);                                   \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE);          \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (":\n", FILE);                                         \
-  fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE);     \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (", TOC[tc0], 0\n", FILE);                             \
-  fputs (TARGET_32BIT                                          \
-        ? "\t.csect .text[PR]\n." : "\t.csect .text[PR],3\n.", FILE); \
-  RS6000_OUTPUT_BASENAME (FILE, NAME);                         \
-  fputs (":\n", FILE);                                         \
-  if (write_symbols == XCOFF_DEBUG)                            \
-    xcoffout_declare_function (FILE, DECL, NAME);              \
-}
-
 /* Return non-zero if this entry is to be written into the constant pool
    in a special way.  We do so if this is a SYMBOL_REF, LABEL_REF or a CONST
    containing one of them.  If -mfp-in-toc (the default), we also do
@@ -2719,19 +2356,6 @@ extern int toc_initialized;
           && BITS_PER_WORD == HOST_BITS_PER_INT)))
 #endif
 
-/* Select section for constant in constant pool.
-
-   On RS/6000, all constants are in the private read-only data area.
-   However, if this is being placed in the TOC it must be output as a
-   toc entry.  */
-
-#define SELECT_RTX_SECTION(MODE, X)            \
-{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X))     \
-    toc_section ();                            \
-  else                                         \
-    read_only_private_data_section ();         \
-}
-
 /* Macro to output a special constant pool entry.  Go to WIN if we output
    it.  Otherwise, it is written the usual way.
 
@@ -2745,114 +2369,38 @@ extern int toc_initialized;
     }                                          \
 }
 
-/* Select the section for an initialized data object.
-
-   On the RS/6000, we have a special section for all variables except those
-   that are static.  */
-
-#define SELECT_SECTION(EXP,RELOC)                      \
-{                                                      \
-  if ((TREE_CODE (EXP) == STRING_CST                   \
-       && ! flag_writable_strings)                     \
-      || (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'd'     \
-         && TREE_READONLY (EXP) && ! TREE_THIS_VOLATILE (EXP) \
-         && DECL_INITIAL (EXP)                         \
-         && (DECL_INITIAL (EXP) == error_mark_node     \
-             || TREE_CONSTANT (DECL_INITIAL (EXP)))    \
-         && ! (RELOC)))                                \
-    {                                                  \
-      if (TREE_PUBLIC (EXP))                           \
-        read_only_data_section ();                     \
-      else                                             \
-        read_only_private_data_section ();             \
-    }                                                  \
-  else                                                 \
-    {                                                  \
-      if (TREE_PUBLIC (EXP))                           \
-        data_section ();                               \
-      else                                             \
-        private_data_section ();                       \
-    }                                                  \
-}
-
-/* This outputs NAME to FILE up to the first null or '['.  */
-
-#define RS6000_OUTPUT_BASENAME(FILE, NAME)     \
-  {                                            \
-    const char *_p;                            \
-                                               \
-    STRIP_NAME_ENCODING (_p, (NAME));          \
-    assemble_name ((FILE), _p);                        \
-  }
-
-/* Remove any trailing [DS] or the like from the symbol name.  */
-
-#define STRIP_NAME_ENCODING(VAR,NAME)                                  \
-  do                                                                   \
-    {                                                                  \
-      const char *_name = (NAME);                                      \
-      int _len;                                                                \
-      if (_name[0] == '*')                                             \
-       _name++;                                                        \
-      _len = strlen (_name);                                           \
-      if (_name[_len - 1] != ']')                                      \
-       (VAR) = _name;                                                  \
-      else                                                             \
-       {                                                               \
-         char *_new_name = (char *) alloca (_len + 1);                 \
-         strcpy (_new_name, _name);                                    \
-         _new_name[_len - 4] = '\0';                                   \
-         (VAR) = _new_name;                                            \
-       }                                                               \
-    }                                                                  \
-  while (0)
-
-/* Output something to declare an external symbol to the assembler.  Most
-   assemblers don't need this.
-
-   If we haven't already, add "[RW]" (or "[DS]" for a function) to the
-   name.  Normally we write this out along with the name.  In the few cases
-   where we can't, it gets stripped off.  */
-
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)  \
-{ rtx _symref = XEXP (DECL_RTL (DECL), 0);     \
-  if ((TREE_CODE (DECL) == VAR_DECL            \
-       || TREE_CODE (DECL) == FUNCTION_DECL)   \
-      && (NAME)[strlen (NAME) - 1] != ']')     \
-    {                                          \
-      char *_name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5); \
-      strcpy (_name, XSTR (_symref, 0));       \
-      strcat (_name, TREE_CODE (DECL) == FUNCTION_DECL ? "[DS]" : "[RW]"); \
-      XSTR (_symref, 0) = _name;               \
-    }                                          \
-  fputs ("\t.extern ", FILE);                  \
-  assemble_name (FILE, XSTR (_symref, 0));     \
-  if (TREE_CODE (DECL) == FUNCTION_DECL)       \
-    {                                          \
-      fputs ("\n\t.extern .", FILE);           \
-      RS6000_OUTPUT_BASENAME (FILE, XSTR (_symref, 0));        \
-    }                                          \
-  putc ('\n', FILE);                           \
-}
-
-/* Similar, but for libcall.  We only have to worry about the function name,
-   not that of the descriptor. */
+/* This is how we tell the assembler that two symbols have the same value.  */
 
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
-{ fputs ("\t.extern .", FILE);                 \
-  assemble_name (FILE, XSTR (FUN, 0));         \
-  putc ('\n', FILE);                           \
-}
+#define SET_ASM_OP ".set"
 
-/* This is how we tell the assembler that two symbols have the same value.  */
+/* This implementes the `alias' attribute.  */
 
-#define ASM_OUTPUT_DEF(FILE,NAME1,NAME2)       \
-do {                                           \
-  fputs("\t.set ", FILE);                      \
-  assemble_name(FILE, NAME1);                  \
-  fputc(',', FILE);                            \
-  assemble_name(FILE, NAME2);                  \
-  fputc('\n', FILE);                           \
+#define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target)    \
+do {                                                   \
+  char * alias = XSTR (XEXP (DECL_RTL (decl), 0), 0);  \
+  char * name = IDENTIFIER_POINTER (target);           \
+  if (TREE_CODE (decl) == FUNCTION_DECL                        \
+      && DEFAULT_ABI == ABI_AIX)                       \
+    {                                                  \
+      if (TREE_PUBLIC (decl))                          \
+       {                                               \
+         fputs ("\t.globl .", FILE);                   \
+         assemble_name (FILE, alias);                  \
+         putc ('\n', FILE);                            \
+       }                                               \
+      else                                             \
+       {                                               \
+         fputs ("\t.lglobl .", FILE);                  \
+         assemble_name (FILE, alias);                  \
+         putc ('\n', FILE);                            \
+       }                                               \
+      fputs ("\t.set .", FILE);                                \
+      assemble_name (FILE, alias);                     \
+      fputs (",.", FILE);                              \
+      assemble_name (FILE, name);                      \
+      fputc ('\n', FILE);                              \
+    }                                                  \
+  ASM_OUTPUT_DEF (FILE, alias, name);                  \
 } while (0)
 
 /* Output to assembler file text saying following lines
@@ -2865,17 +2413,6 @@ do {                                             \
 
 #define ASM_APP_OFF ""
 
-/* Output before instructions.
-   Text section for 64-bit target may contain 64-bit address jump table.  */
-
-#define TEXT_SECTION_ASM_OP (TARGET_32BIT \
-                            ? "\t.csect .text[PR]" : "\t.csect .text[PR],3")
-
-/* Output before writable data.
-   Align entire section to BIGGEST_ALIGNMENT.  */
-
-#define DATA_SECTION_ASM_OP ".csect .data[RW],3"
-
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
 
@@ -2963,7 +2500,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0). */
   &rs6000_reg_names[74][0],    /* cr6  */                              \
   &rs6000_reg_names[75][0],    /* cr7  */                              \
                                                                        \
-  &rs6000_reg_names[76][0],    /* fpmem */                             \
+  &rs6000_reg_names[76][0],    /* xer  */                              \
 }
 
 /* print-rtl can't handle the above REGISTER_NAMES, so define the
@@ -2982,7 +2519,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0). */
     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",            \
      "mq",  "lr", "ctr",  "ap",                                                \
     "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",            \
-  "fpmem"                                                              \
+  "xer"                                                                        \
 }
 
 /* Table of additional register names to use in user input.  */
@@ -3017,52 +2554,6 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0). */
    the loader.  This depends on the AIX version.  */
 #define RS6000_CALL_GLUE "cror 31,31,31"
 
-/* This is how to output the definition of a user-level label named NAME,
-   such as the label on a static function or variable NAME.  */
-
-#define ASM_OUTPUT_LABEL(FILE,NAME)    \
-  do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0)
-
-/* This is how to output a command to make the user-level label named NAME
-   defined for reference from other files.  */
-
-#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
-  do { fputs ("\t.globl ", FILE);      \
-       RS6000_OUTPUT_BASENAME (FILE, NAME); putc ('\n', FILE);} while (0)
-
-/* This is how to output a reference to a user-level label named NAME.
-   `assemble_name' uses this.  */
-
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-  fputs (NAME, FILE)
-
-/* This is how to output an internal numbered label where
-   PREFIX is the class of label and NUM is the number within the class.  */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM)     \
-  fprintf (FILE, "%s..%d:\n", PREFIX, NUM)
-
-/* This is how to output an internal label prefix.  rs6000.c uses this
-   when generating traceback tables.  */
-
-#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX)  \
-  fprintf (FILE, "%s..", PREFIX)
-
-/* This is how to output a label for a jump table.  Arguments are the same as
-   for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
-   passed. */
-
-#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)       \
-{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
-
-/* This is how to store into the string LABEL
-   the symbol_ref name of an internal numbered label where
-   PREFIX is the class of label and NUM is the number within the class.
-   This is suitable for output with `assemble_name'.  */
-
-#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
-  sprintf (LABEL, "*%s..%d", PREFIX, NUM)
-
 /* This is how to output an assembler line defining a `double' constant.  */
 
 #define ASM_OUTPUT_DOUBLE(FILE, VALUE)                 \
@@ -3070,7 +2561,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0). */
     long t[2];                                         \
     REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);          \
     fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n",   \
-            t[0] & 0xffffffff, t[1] & 0xffffffff);     \
+            t[0] & 0xffffffffu, t[1] & 0xffffffffu);   \
   }
 
 /* This is how to output an assembler line defining a `float' constant.  */
@@ -3079,7 +2570,7 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0). */
   {                                                    \
     long t;                                            \
     REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);          \
-    fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \
+    fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffffu);        \
   }
 
 /* This is how to output an assembler line defining an `int' constant.  */
@@ -3123,22 +2614,8 @@ do {                                                                     \
 #define ASM_OUTPUT_BYTE(FILE,VALUE)  \
   fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
 
-/* This is how to output an assembler line to define N characters starting
-   at P to FILE.  */
-
-#define ASM_OUTPUT_ASCII(FILE, P, N)  output_ascii ((FILE), (P), (N))
-
-/* This is how to output an element of a case-vector that is absolute.
-   (RS/6000 does not use such vectors, but we must define this macro
-   anyway.)   */
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)           \
-  do { char buf[100];                                  \
-       fputs ("\t.long ", FILE);                       \
-       ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE);  \
-       assemble_name (FILE, buf);                      \
-       putc ('\n', FILE);                              \
-     } while (0)
+/* This is used by the definition of ASM_OUTPUT_ADDR_ELT in defaults.h.  */
+#define ASM_LONG (TARGET_32BIT ? ".long" : ".quad")
 
 /* This is how to output an element of a case-vector that is relative.  */
 
@@ -3161,21 +2638,6 @@ do {                                                                     \
   if ((LOG) != 0)                      \
     fprintf (FILE, "\t.align %d\n", (LOG))
 
-#define ASM_OUTPUT_SKIP(FILE,SIZE)  \
-  fprintf (FILE, "\t.space %d\n", (SIZE))
-
-/* This says how to output an assembler line
-   to define a global common symbol.  */
-
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \
-  do { fputs (".comm ", (FILE));                       \
-       RS6000_OUTPUT_BASENAME ((FILE), (NAME));                \
-       if ( (SIZE) > 4)                                        \
-         fprintf ((FILE), ",%d,3\n", (SIZE));          \
-       else                                            \
-        fprintf( (FILE), ",%d\n", (SIZE));             \
-  } while (0)
-
 /* This says how to output an assembler line
    to define a local common symbol.
    Alignment cannot be specified, but we can try to maintain
@@ -3203,6 +2665,12 @@ do {                                                                     \
 #define ASM_OPEN_PAREN "("
 #define ASM_CLOSE_PAREN ")"
 
+/* Pick up the return address upon entry to a procedure. Used for
+   dwarf2 unwind information.  This also enables the table driven
+   mechanism.  */
+
+#define INCOMING_RETURN_ADDR_RTX   gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+
 /* Define results of standard character escape sequences.  */
 #define TARGET_BELL 007
 #define TARGET_BS 010
@@ -3240,6 +2708,7 @@ do {                                                                      \
   {"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}},      \
   {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}},        \
   {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}},           \
+  {"reg_or_u_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
   {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}},             \
   {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}},           \
   {"easy_fp_constant", {CONST_DOUBLE}},                                \
@@ -3253,11 +2722,13 @@ do {                                                                    \
   {"and_operand", {SUBREG, REG, CONST_INT}},                   \
   {"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}},   \
   {"logical_operand", {SUBREG, REG, CONST_INT}},               \
+  {"logical_u_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
   {"non_logical_cint_operand", {CONST_INT}},                   \
+  {"non_logical_u_cint_operand", {CONST_INT, CONST_DOUBLE}},   \
   {"mask_operand", {CONST_INT}},                               \
   {"mask64_operand", {CONST_INT, CONST_DOUBLE}},               \
   {"count_register_operand", {REG}},                           \
-  {"fpmem_operand", {REG}},                                    \
+  {"xer_operand", {REG}},                                      \
   {"call_operand", {SYMBOL_REF, REG}},                         \
   {"current_file_function_operand", {SYMBOL_REF}},             \
   {"input_operand", {SUBREG, MEM, REG, CONST_INT,              \
@@ -3285,109 +2756,3 @@ extern int flag_pic;
 extern int optimize;
 extern int flag_expensive_optimizations;
 extern int frame_pointer_needed;
-
-/* Declare functions in rs6000.c */
-extern void optimization_options ();
-extern void output_options ();
-extern void rs6000_override_options ();
-extern void rs6000_file_start ();
-extern struct rtx_def *rs6000_float_const ();
-extern struct rtx_def *rs6000_got_register ();
-extern struct rtx_def *find_addr_reg();
-extern int direct_return ();
-extern int get_issue_rate ();
-extern int any_operand ();
-extern int short_cint_operand ();
-extern int u_short_cint_operand ();
-extern int non_short_cint_operand ();
-extern int gpc_reg_operand ();
-extern int cc_reg_operand ();
-extern int cc_reg_not_cr0_operand ();
-extern int reg_or_short_operand ();
-extern int reg_or_neg_short_operand ();
-extern int reg_or_u_short_operand ();
-extern int reg_or_cint_operand ();
-extern int got_operand ();
-extern int got_no_const_operand ();
-extern int num_insns_constant ();
-extern int easy_fp_constant ();
-extern int volatile_mem_operand ();
-extern int offsettable_mem_operand ();
-extern int mem_or_easy_const_operand ();
-extern int add_operand ();
-extern int non_add_cint_operand ();
-extern int non_logical_cint_operand ();
-extern int logical_operand ();
-extern int mask_operand ();
-extern int mask64_operand ();
-extern int and64_operand ();
-extern int and_operand ();
-extern int count_register_operand ();
-extern int fpmem_operand ();
-extern int reg_or_mem_operand ();
-extern int lwa_operand ();
-extern int call_operand ();
-extern int current_file_function_operand ();
-extern int input_operand ();
-extern int small_data_operand ();
-extern void init_cumulative_args ();
-extern void function_arg_advance ();
-extern int function_arg_boundary ();
-extern struct rtx_def *function_arg ();
-extern int function_arg_partial_nregs ();
-extern int function_arg_pass_by_reference ();
-extern void setup_incoming_varargs ();
-extern union tree_node *rs6000_build_va_list ();
-extern void rs6000_va_start ();
-extern struct rtx_def *rs6000_va_arg ();
-extern struct rtx_def *rs6000_stack_temp ();
-extern int expand_block_move ();
-extern int load_multiple_operation ();
-extern int store_multiple_operation ();
-extern int branch_comparison_operator ();
-extern int scc_comparison_operator ();
-extern int trap_comparison_operator ();
-extern int includes_lshift_p ();
-extern int includes_rshift_p ();
-extern int registers_ok_for_quad_peep ();
-extern int addrs_ok_for_quad_peep ();
-extern enum reg_class secondary_reload_class ();
-extern int ccr_bit ();
-extern void rs6000_finalize_pic ();
-extern void rs6000_reorg ();
-extern void rs6000_save_machine_status ();
-extern void rs6000_restore_machine_status ();
-extern void rs6000_init_expanders ();
-extern void print_operand ();
-extern void print_operand_address ();
-extern int first_reg_to_save ();
-extern int first_fp_reg_to_save ();
-extern int rs6000_makes_calls ();
-extern rs6000_stack_t *rs6000_stack_info ();
-extern void output_prolog ();
-extern void output_epilog ();
-extern void output_mi_thunk ();
-extern void output_toc ();
-extern void output_ascii ();
-extern void rs6000_gen_section_name ();
-extern void output_function_profiler ();
-extern int rs6000_adjust_cost ();
-extern int rs6000_adjust_priority ();
-extern void rs6000_trampoline_template ();
-extern int rs6000_trampoline_size ();
-extern void rs6000_initialize_trampoline ();
-extern void rs6000_output_load_toc_table ();
-extern int rs6000_comp_type_attributes ();
-extern int rs6000_valid_decl_attribute_p ();
-extern int rs6000_valid_type_attribute_p ();
-extern void rs6000_set_default_type_attributes ();
-extern struct rtx_def *rs6000_dll_import_ref ();
-extern struct rtx_def *rs6000_longcall_ref ();
-extern int function_arg_padding ();
-extern void toc_section ();
-extern void private_data_section ();
-extern void rs6000_fatal_bad_address ();
-
-/* See nonlocal_goto_receiver for when this must be set.  */
-
-#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_TOC && TARGET_MINIMAL_TOC)
index 5620eb4..2e23778 100644 (file)
@@ -1,6 +1,6 @@
 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
-;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 
+;; 1999, 2000 Free Software Foundation, Inc.
 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
 ;; This file is part of GNU CC.
 ;; Boston, MA 02111-1307, USA.
 
 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
+
+;; `unspec' values used in rs6000.md:
+;; Number      Use
+;; 0           frsp for POWER machines
+;; 0/v         blockage
+;; 5           used to tie the stack contents and the stack pointer
+;; 6           address of a word pointing to the TOC
+;; 7           address of the TOC (more-or-less)
+;; 8           movsi_got
+;; 9/v         eh_reg_restore
+;; 10          fctiwz
+;; 19          movesi_from_cr
+;; 20          movesi_to_cr
 \f
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "rldicl. %2,%1,0,56"
-  [(set_attr "type" "compare")])
+  "@
+   rldicl. %2,%1,0,56
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (zero_extend:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "rldicl. %0,%1,0,56"
-  [(set_attr "type" "compare")])
+  "@
+   rldicl. %0,%1,0,56
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (zero_extend:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "extendqidi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "extsb %0,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "extsb. %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsb. %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (sign_extend:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (sign_extend:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "extsb. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsb. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (sign_extend:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (sign_extend:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "zero_extendhidi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "rldicl. %2,%1,0,48"
-  [(set_attr "type" "compare")])
+  "@
+   rldicl. %2,%1,0,48
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (zero_extend:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "rldicl. %0,%1,0,48"
-  [(set_attr "type" "compare")])
+  "@
+   rldicl. %0,%1,0,48
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (zero_extend:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "extendhidi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "extsh. %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsh. %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (sign_extend:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (sign_extend:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "extsh. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsh. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (sign_extend:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (sign_extend:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "zero_extendsidi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "rldicl. %2,%1,0,32"
-  [(set_attr "type" "compare")])
+  "@
+   rldicl. %2,%1,0,32
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (zero_extend:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "rldicl. %0,%1,0,32"
-  [(set_attr "type" "compare")])
+  "@
+   rldicl. %0,%1,0,32
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (zero_extend:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "extendsidi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "extsw. %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsw. %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (sign_extend:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (sign_extend:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "extsw. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsw. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (sign_extend:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (sign_extend:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "zero_extendqisi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r"))]
+   (clobber (match_scratch:SI 2 "=r,r"))]
   ""
-  "{andil.|andi.} %2,%1,0xff"
-  [(set_attr "type" "compare")])
+  "@
+   {andil.|andi.} %2,%1,0xff
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 2 ""))]
+  "reload_completed"
+  [(set (match_dup 2)
+       (zero_extend:SI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:SI (match_dup 1)))]
   ""
-  "{andil.|andi.} %0,%1,0xff"
-  [(set_attr "type" "compare")])
+  "@
+   {andil.|andi.} %0,%1,0xff
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (zero_extend:SI (match_dup 1)))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:SI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "extendqisi2"
   [(use (match_operand:SI 0 "gpc_reg_operand" ""))
   "extsb %0,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r"))]
+   (clobber (match_scratch:SI 2 "=r,r"))]
   "TARGET_POWERPC"
-  "extsb. %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsb. %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 2 ""))]
+  "TARGET_POWERPC && reload_completed"
+  [(set (match_dup 2)
+       (sign_extend:SI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (sign_extend:SI (match_dup 1)))]
   "TARGET_POWERPC"
-  "extsb. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsb. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (sign_extend:SI (match_dup 1)))]
+  "TARGET_POWERPC && reload_completed"
+  [(set (match_dup 0)
+       (sign_extend:SI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "extendqisi2_power"
   [(parallel [(set (match_dup 2)
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:HI 2 "=r"))]
+   (clobber (match_scratch:HI 2 "=r,r"))]
   ""
-  "{andil.|andi.} %2,%1,0xff"
-  [(set_attr "type" "compare")])
+  "@
+   {andil.|andi.} %2,%1,0xff
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:HI 2 ""))]
+  "reload_completed"
+  [(set (match_dup 2)
+       (zero_extend:HI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:HI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:HI (match_dup 1)))]
   ""
-  "{andil.|andi.} %0,%1,0xff"
-  [(set_attr "type" "compare")])
+  "@
+   {andil.|andi.} %0,%1,0xff
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:HI 0 "gpc_reg_operand" "")
+       (zero_extend:HI (match_dup 1)))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:HI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "extendqihi2"
   [(use (match_operand:HI 0 "gpc_reg_operand" ""))
   "extsb %0,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:HI 2 "=r"))]
+   (clobber (match_scratch:HI 2 "=r,r"))]
   "TARGET_POWERPC"
-  "extsb. %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsb. %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:HI 2 ""))]
+  "TARGET_POWERPC && reload_completed"
+  [(set (match_dup 2)
+       (sign_extend:HI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:HI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
        (sign_extend:HI (match_dup 1)))]
   "TARGET_POWERPC"
-  "extsb. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   extsb. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:HI 0 "gpc_reg_operand" "")
+       (sign_extend:HI (match_dup 1)))]
+  "TARGET_POWERPC && reload_completed"
+  [(set (match_dup 0)
+       (sign_extend:HI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "extendqihi2_power"
   [(parallel [(set (match_dup 2)
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r"))]
+   (clobber (match_scratch:SI 2 "=r,r"))]
   ""
-  "{andil.|andi.} %2,%1,0xffff"
-  [(set_attr "type" "compare")])
+  "@
+   {andil.|andi.} %2,%1,0xffff
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 2 ""))]
+  "reload_completed"
+  [(set (match_dup 2)
+       (zero_extend:SI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:SI (match_dup 1)))]
   ""
-  "{andil.|andi.} %0,%1,0xffff"
-  [(set_attr "type" "compare")])
+  "@
+   {andil.|andi.} %0,%1,0xffff
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (zero_extend:SI (match_dup 1)))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:SI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "extendhisi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
   [(set_attr "type" "load,*")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r"))]
+   (clobber (match_scratch:SI 2 "=r,r"))]
   ""
-  "{exts.|extsh.} %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   {exts.|extsh.} %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 2 ""))]
+  "reload_completed"
+  [(set (match_dup 2)
+       (sign_extend:SI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (sign_extend:SI (match_dup 1)))]
   ""
-  "{exts.|extsh.} %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   {exts.|extsh.} %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
 \f
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (sign_extend:SI (match_dup 1)))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (sign_extend:SI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
 ;; Fixed-point arithmetic insns.
 
 ;; Discourage ai/addic because of carry but provide it in an alternative
       if (low & 0x8000)
         high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
 
+      /* The ordering here is important for the prolog expander.
+        When space is allocated from the stack, adding 'low' first may
+        produce a temporary deallocation (which would be bad).  */
       emit_insn (gen_addsi3 (tmp, operands[1], GEN_INT (high)));
       emit_insn (gen_addsi3 (operands[0], tmp, GEN_INT (low)));
       DONE;
   "doz%I2 %0,%1,%2")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
-                             (match_operand:SI 2 "reg_or_short_operand" "rI"))
+        (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                             (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
                          (const_int 0)
                          (minus:SI (match_dup 2) (match_dup 1)))
         (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "TARGET_POWER"
-  "doz%I2. %3,%1,%2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   doz%I2. %3,%1,%2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "")
+                             (match_operand:SI 2 "reg_or_short_operand" ""))
+                         (const_int 0)
+                         (minus:SI (match_dup 2) (match_dup 1)))
+        (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 3)
+       (if_then_else:SI (gt (match_dup 1) (match_dup 2))
+                         (const_int 0)
+                         (minus:SI (match_dup 2) (match_dup 1))))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
-                             (match_operand:SI 2 "reg_or_short_operand" "rI"))
+        (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                             (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
                          (const_int 0)
                          (minus:SI (match_dup 2) (match_dup 1)))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (if_then_else:SI (gt (match_dup 1) (match_dup 2))
                         (const_int 0)
                         (minus:SI (match_dup 2) (match_dup 1))))]
   "TARGET_POWER"
-  "doz%I2. %0,%1,%2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   doz%I2. %0,%1,%2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "")
+                             (match_operand:SI 2 "reg_or_short_operand" ""))
+                         (const_int 0)
+                         (minus:SI (match_dup 2) (match_dup 1)))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (if_then_else:SI (gt (match_dup 1) (match_dup 2))
+                        (const_int 0)
+                        (minus:SI (match_dup 2) (match_dup 1))))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (if_then_else:SI (gt (match_dup 1) (match_dup 2))
+                        (const_int 0)
+                        (minus:SI (match_dup 2) (match_dup 1))))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; We don't need abs with condition code because such comparisons should
 ;; never be done.
   "neg %0,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r"))]
+   (clobber (match_scratch:SI 2 "=r,r"))]
   "! TARGET_POWERPC64"
-  "neg. %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   neg. %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 2 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (neg:SI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (neg:SI (match_dup 1)))]
   "! TARGET_POWERPC64"
-  "neg. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   neg. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (neg:SI (match_dup 1)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (neg:SI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "ffssi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
    [(set_attr "type" "imul")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
-                            (match_operand:SI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+                            (match_operand:SI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))
-   (clobber (match_scratch:SI 4 "=q"))]
+   (clobber (match_scratch:SI 3 "=r,r"))
+   (clobber (match_scratch:SI 4 "=q,q"))]
   "TARGET_POWER"
-  "{muls.|mullw.} %3,%1,%2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {muls.|mullw.} %3,%1,%2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                            (match_operand:SI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 3)
+       (mult:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
-                            (match_operand:SI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+                            (match_operand:SI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "! TARGET_POWER"
-  "{muls.|mullw.} %3,%1,%2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {muls.|mullw.} %3,%1,%2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                            (match_operand:SI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWER && reload_completed"
+  [(set (match_dup 3)
+       (mult:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
-                            (match_operand:SI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+                            (match_operand:SI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (mult:SI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=q"))]
+   (clobber (match_scratch:SI 4 "=q,q"))]
   "TARGET_POWER"
-  "{muls.|mullw.} %0,%1,%2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {muls.|mullw.} %0,%1,%2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                            (match_operand:SI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (mult:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (mult:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
-                            (match_operand:SI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+                            (match_operand:SI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (mult:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWER"
-  "{muls.|mullw.} %0,%1,%2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {muls.|mullw.} %0,%1,%2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                            (match_operand:SI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (mult:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (mult:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; Operand 1 is divided by operand 2; quotient goes to operand
 ;; 0 and remainder to operand 3.
   [(set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                           (match_operand:SI 2 "const_int_operand" "N"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:SI 2 "const_int_operand" "N,N"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "exact_log2 (INTVAL (operands[2])) >= 0"
-  "{srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3"
+  "@
+   {srai|srawi} %3,%1,%p2\;{aze.|addze.} %3,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                           (match_operand:SI 2 "const_int_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
+  [(set (match_dup 3)
+       (div:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                           (match_operand:SI 2 "const_int_operand" "N"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:SI 2 "const_int_operand" "N,N"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (div:SI (match_dup 1) (match_dup 2)))]
   "exact_log2 (INTVAL (operands[2])) >= 0"
-  "{srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0"
+  "@
+   {srai|srawi} %0,%1,%p2\;{aze.|addze.} %0,%0
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                           (match_operand:SI 2 "const_int_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (div:SI (match_dup 1) (match_dup 2)))]
+  "exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
+  [(set (match_dup 0)
+       (div:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
    and %0,%1,%2
    {rlinm|rlwinm} %0,%1,0,%m2,%M2
    {andil.|andi.} %0,%1,%b2
-   {andiu.|andis.} %0,%1,%u2"
-  [(set_attr "length" "4")])
+   {andiu.|andis.} %0,%1,%u2")
 
 ;; Note to set cr's other than cr0 we do the and immediate and then
 ;; the test again -- this avoids a mcrf which on the higher end
   "maskir %0,%3,%2")
 
 (define_insn "*maskir_internal5"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
-                        (match_operand:SI 1 "gpc_reg_operand" "0"))
+        (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))
+                        (match_operand:SI 1 "gpc_reg_operand" "0,0"))
                 (and:SI (match_dup 2)
-                        (match_operand:SI 3 "gpc_reg_operand" "r")))
+                        (match_operand:SI 3 "gpc_reg_operand" "r,r")))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
                (and:SI (match_dup 2) (match_dup 3))))]
   "TARGET_POWER"
-  "maskir. %0,%3,%2"
-  [(set_attr "type" "compare")])
+  "@
+   maskir. %0,%3,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))
+                        (match_operand:SI 1 "gpc_reg_operand" ""))
+                (and:SI (match_dup 2)
+                        (match_operand:SI 3 "gpc_reg_operand" "")))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
+               (and:SI (match_dup 2) (match_dup 3))))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
+               (and:SI (match_dup 2) (match_dup 3))))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*maskir_internal6"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
-                        (match_operand:SI 1 "gpc_reg_operand" "0"))
-                (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
+        (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))
+                        (match_operand:SI 1 "gpc_reg_operand" "0,0"))
+                (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r")
                         (match_dup 2)))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
                (and:SI (match_dup 3) (match_dup 2))))]
   "TARGET_POWER"
-  "maskir. %0,%3,%2"
-  [(set_attr "type" "compare")])
+  "@
+   maskir. %0,%3,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))
+                        (match_operand:SI 1 "gpc_reg_operand" ""))
+                (and:SI (match_operand:SI 3 "gpc_reg_operand" "")
+                        (match_dup 2)))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
+               (and:SI (match_dup 3) (match_dup 2))))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
+               (and:SI (match_dup 3) (match_dup 2))))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*maskir_internal7"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
-                        (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 3 "gpc_reg_operand" "r,r"))
                 (and:SI (not:SI (match_dup 2))
-                        (match_operand:SI 1 "gpc_reg_operand" "0")))
+                        (match_operand:SI 1 "gpc_reg_operand" "0,0")))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ior:SI (and:SI (match_dup 2) (match_dup 3))
                (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
   "TARGET_POWER"
-  "maskir. %0,%3,%2"
-  [(set_attr "type" "compare")])
+  "@
+   maskir. %0,%3,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "")
+                        (match_operand:SI 3 "gpc_reg_operand" ""))
+                (and:SI (not:SI (match_dup 2))
+                        (match_operand:SI 1 "gpc_reg_operand" "")))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ior:SI (and:SI (match_dup 2) (match_dup 3))
+               (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (ior:SI (and:SI (match_dup 2) (match_dup 3))
+               (and:SI (not:SI (match_dup 2)) (match_dup 1))))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*maskir_internal8"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "gpc_reg_operand" "r"))
+        (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "gpc_reg_operand" "r,r"))
                 (and:SI (not:SI (match_dup 2))
-                        (match_operand:SI 1 "gpc_reg_operand" "0")))
+                        (match_operand:SI 1 "gpc_reg_operand" "0,0")))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ior:SI (and:SI (match_dup 3) (match_dup 2))
                (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
   "TARGET_POWER"
-  "maskir. %0,%3,%2"
-  [(set_attr "type" "compare")])
+  "@
+   maskir. %0,%3,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
 \f
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "gpc_reg_operand" ""))
+                (and:SI (not:SI (match_dup 2))
+                        (match_operand:SI 1 "gpc_reg_operand" "")))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ior:SI (and:SI (match_dup 3) (match_dup 2))
+               (and:SI (not:SI (match_dup 2)) (match_dup 1))))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (ior:SI (and:SI (match_dup 3) (match_dup 2))
+               (and:SI (not:SI (match_dup 2)) (match_dup 1))))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
 ;; Rotate and shift insns, in all their variants.  These support shifts,
 ;; field inserts and extracts, and various combinations thereof.
 (define_expand "insv"
 }")
 
 (define_insn "*extzvsi_internal1"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "const_int_operand" "i")
-                        (match_operand:SI 3 "const_int_operand" "i"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "const_int_operand" "i,i")
+                        (match_operand:SI 3 "const_int_operand" "i,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r"))]
+   (clobber (match_scratch:SI 4 "=r,r"))]
   "! TARGET_POWERPC64"
   "*
 {
   int start = INTVAL (operands[3]) & 31;
   int size = INTVAL (operands[2]) & 31;
 
+  /* Force split for non-cc0 compare.  */
+  if (which_alternative == 1)
+     return \"#\";
+
   /* If the bitfield being tested fits in the upper or lower half of a
      word, it is possible to use andiu. or andil. to test it.  This is
      useful because the condition register set-use delay is smaller for
     operands[3] = GEN_INT (start + size);
   return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
 }"
-  [(set_attr "type" "compare")])
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "const_int_operand" "")
+                        (match_operand:SI 3 "const_int_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (zero_extract:SI (match_dup 1) (match_dup 2)
+                        (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*extzvsi_internal2"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
-       (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "const_int_operand" "i")
-                        (match_operand:SI 3 "const_int_operand" "i"))
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+       (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "const_int_operand" "i,i")
+                        (match_operand:SI 3 "const_int_operand" "i,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
   "! TARGET_POWERPC64"
   "*
   int start = INTVAL (operands[3]) & 31;
   int size = INTVAL (operands[2]) & 31;
 
+  /* Force split for non-cc0 compare.  */
+  if (which_alternative == 1)
+     return \"#\";
+
   if (start >= 16 && start + size == 32)
     {
       operands[3] = GEN_INT ((1 << (32 - start)) - 1);
     operands[3] = GEN_INT (start + size);
   return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
 }"
-  [(set_attr "type" "delayed_compare")])
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "const_int_operand" "")
+                        (match_operand:SI 3 "const_int_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "extzvdi"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
 
 (define_insn "*rotlsi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "! TARGET_POWERPC64"
-  "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (rotate:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotlsi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (rotate:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWERPC64"
-  "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (rotate:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (rotate:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotlsi3_internal4"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
 
 (define_insn "*rotlsi3_internal5"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (and:SI
-                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                               (match_operand:SI 2 "reg_or_cint_operand" "ri"))
-                    (match_operand:SI 3 "mask_operand" "T"))
+                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                               (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+                    (match_operand:SI 3 "mask_operand" "T,T"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r"))]
+   (clobber (match_scratch:SI 4 "=r,r"))]
   "! TARGET_POWERPC64"
-  "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:SI
+                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                               (match_operand:SI 2 "reg_or_cint_operand" ""))
+                    (match_operand:SI 3 "mask_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (and:SI (rotate:SI (match_dup 1)
+                               (match_dup 2))
+                    (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotlsi3_internal6"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC (and:SI
-                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                               (match_operand:SI 2 "reg_or_cint_operand" "ri"))
-                    (match_operand:SI 3 "mask_operand" "T"))
+                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                               (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
+                    (match_operand:SI 3 "mask_operand" "T,T"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "! TARGET_POWERPC64"
-  "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:SI
+                    (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                               (match_operand:SI 2 "reg_or_cint_operand" ""))
+                    (match_operand:SI 3 "mask_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotlsi3_internal7"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
 
 (define_insn "*rotlsi3_internal8"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:SI
                     (subreg:QI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   ""
-  "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI
+                    (subreg:QI
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "reload_completed"
+  [(set (match_dup 3)
+       (zero_extend:SI (subreg:QI
+                     (rotate:SI (match_dup 1)
+                                (match_dup 2)) 0)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotlsi3_internal9"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:SI
                     (subreg:QI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
   ""
-  "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI
+                    (subreg:QI
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotlsi3_internal10"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
 
 (define_insn "*rotlsi3_internal11"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:SI
                     (subreg:HI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   ""
-  "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI
+                    (subreg:HI
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "reload_completed"
+  [(set (match_dup 3)
+       (zero_extend:SI (subreg:HI
+                     (rotate:SI (match_dup 1)
+                                (match_dup 2)) 0)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotlsi3_internal12"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:SI
                     (subreg:HI
-                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
   ""
-  "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:SI
+                    (subreg:HI
+                     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; Note that we use "sle." instead of "sl." so that we can set
 ;; SHIFT_COUNT_TRUNCATED.
   "TARGET_POWER"
   "@
    sle %0,%1,%2
-   {sli|slwi} %0,%1,%h2"
-  [(set_attr "length" "8")])
+   {sli|slwi} %0,%1,%h2")
 
 (define_insn "ashlsi3_no_power"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                   (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
   "! TARGET_POWER"
-  "{sl|slw}%I2 %0,%1,%h2"
-  [(set_attr "length" "8")])
+  "{sl|slw}%I2 %0,%1,%h2")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
-       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))
-   (clobber (match_scratch:SI 4 "=q,X"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))
+   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
   "TARGET_POWER"
   "@
    sle. %3,%1,%2
-   {sli.|slwi.} %3,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+   {sli.|slwi.} %3,%1,%h2
+   #
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 3)
+       (ashift:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "! TARGET_POWER && ! TARGET_POWERPC64"
-  "{sl|slw}%I2. %3,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {sl|slw}%I2. %3,%1,%h2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (ashift:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
-       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (ashift:SI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=q,X"))]
+   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
   "TARGET_POWER"
   "@
    sle. %0,%1,%2
-   {sli.|slwi.} %0,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+   {sli.|slwi.} %0,%1,%h2
+   #
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ashift:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (ashift:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ashift:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWER && ! TARGET_POWERPC64"
-  "{sl|slw}%I2. %0,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {sl|slw}%I2. %0,%1,%h2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ashift:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ashift:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                           (match_operand:SI 2 "const_int_operand" "i"))
-                (match_operand:SI 3 "mask_operand" "T"))
+        (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:SI 2 "const_int_operand" "i,i"))
+                (match_operand:SI 3 "mask_operand" "T,T"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r"))]
+   (clobber (match_scratch:SI 4 "=r,r"))]
   "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])"
-  "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                           (match_operand:SI 2 "const_int_operand" ""))
+                (match_operand:SI 3 "mask_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed"
+  [(set (match_dup 4)
+       (and:SI (ashift:SI (match_dup 1) (match_dup 2))
+                (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                           (match_operand:SI 2 "const_int_operand" "i"))
-                (match_operand:SI 3 "mask_operand" "T"))
+        (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:SI 2 "const_int_operand" "i,i"))
+                (match_operand:SI 3 "mask_operand" "T,T"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])"
-  "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                           (match_operand:SI 2 "const_int_operand" ""))
+                (match_operand:SI 3 "mask_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+  "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed"
+  [(set (match_dup 0)
+       (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; The AIX assembler mis-handles "sri x,x,0", so write that case as
 ;; "sli x,x,0".
   {sr|srw}%I2 %0,%1,%h2")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x")
-       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,r,O,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,X,r"))
-   (clobber (match_scratch:SI 4 "=q,X,X"))]
+   (clobber (match_scratch:SI 3 "=r,X,r,r,X,r"))
+   (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))]
   "TARGET_POWER"
   "@
   sre. %3,%1,%2
   mr. %1,%1
-  {s%A2i.|s%A2wi.} %3,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+  {s%A2i.|s%A2wi.} %3,%1,%h2
+  #
+  #
+  #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,4,8,8,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 3)
+       (lshiftrt:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
-       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=X,r"))]
+   (clobber (match_scratch:SI 3 "=X,r,X,r"))]
   "! TARGET_POWER && ! TARGET_POWERPC64"
   "@
    mr. %1,%1
-   {sr|srw}%I2. %3,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+   {sr|srw}%I2. %3,%1,%h2
+   #
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,8,8")])
 
-(define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x")
-       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "r,O,i"))
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (lshiftrt:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
+
+(define_insn ""
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,r,O,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
        (lshiftrt:SI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=q,X,X"))]
+   (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))]
   "TARGET_POWER"
   "@
   sre. %0,%1,%2
   mr. %0,%1
-  {s%A2i.|s%A2wi.} %0,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+  {s%A2i.|s%A2wi.} %0,%1,%h2
+  #
+  #
+  #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,4,8,8,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (lshiftrt:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (lshiftrt:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
-       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (lshiftrt:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWER && ! TARGET_POWERPC64"
   "@
    mr. %0,%1
-   {sr|srw}%I2. %0,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+   {sr|srw}%I2. %0,%1,%h2
+   #
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (lshiftrt:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (lshiftrt:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                             (match_operand:SI 2 "const_int_operand" "i"))
-                (match_operand:SI 3 "mask_operand" "T"))
+        (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                             (match_operand:SI 2 "const_int_operand" "i,i"))
+                (match_operand:SI 3 "mask_operand" "T,T"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r"))]
+   (clobber (match_scratch:SI 4 "=r,r"))]
   "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])"
-  "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                             (match_operand:SI 2 "const_int_operand" ""))
+                (match_operand:SI 3 "mask_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed"
+  [(set (match_dup 4)
+       (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
+                (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                             (match_operand:SI 2 "const_int_operand" "i"))
-                (match_operand:SI 3 "mask_operand" "T"))
+        (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                             (match_operand:SI 2 "const_int_operand" "i,i"))
+                (match_operand:SI 3 "mask_operand" "T,T"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])"
-  "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                             (match_operand:SI 2 "const_int_operand" ""))
+                (match_operand:SI 3 "mask_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+  "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed"
+  [(set (match_dup 0)
+       (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "{rlinm|rlwinm} %0,%1,%s2,0xff")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (zero_extend:SI
          (subreg:QI
-          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                       (match_operand:SI 2 "const_int_operand" "i")) 0))
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                       (match_operand:SI 2 "const_int_operand" "i,i")) 0))
         (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "includes_rshift_p (operands[2], GEN_INT (255))"
-  "{rlinm.|rlwinm.} %3,%1,%s2,0xff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %3,%1,%s2,0xff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (zero_extend:SI
+         (subreg:QI
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                       (match_operand:SI 2 "const_int_operand" "")) 0))
+        (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
+  [(set (match_dup 3)
+       (zero_extend:SI (subreg:QI
+          (lshiftrt:SI (match_dup 1)
+                       (match_dup 2)) 0)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
         (zero_extend:SI
          (subreg:QI
-          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                       (match_operand:SI 2 "const_int_operand" "i")) 0))
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                       (match_operand:SI 2 "const_int_operand" "i,i")) 0))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
   "includes_rshift_p (operands[2], GEN_INT (255))"
-  "{rlinm.|rlwinm.} %0,%1,%s2,0xff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %0,%1,%s2,0xff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (zero_extend:SI
+         (subreg:QI
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                       (match_operand:SI 2 "const_int_operand" "")) 0))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
+  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "{rlinm|rlwinm} %0,%1,%s2,0xffff")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (zero_extend:SI
          (subreg:HI
-          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                       (match_operand:SI 2 "const_int_operand" "i")) 0))
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                       (match_operand:SI 2 "const_int_operand" "i,i")) 0))
         (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "includes_rshift_p (operands[2], GEN_INT (65535))"
-  "{rlinm.|rlwinm.} %3,%1,%s2,0xffff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %3,%1,%s2,0xffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (zero_extend:SI
+         (subreg:HI
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                       (match_operand:SI 2 "const_int_operand" "")) 0))
+        (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
+  [(set (match_dup 3)
+       (zero_extend:SI (subreg:HI
+          (lshiftrt:SI (match_dup 1)
+                       (match_dup 2)) 0)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
         (zero_extend:SI
          (subreg:HI
-          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                       (match_operand:SI 2 "const_int_operand" "i")) 0))
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                       (match_operand:SI 2 "const_int_operand" "i,i")) 0))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
   "includes_rshift_p (operands[2], GEN_INT (65535))"
-  "{rlinm.|rlwinm.} %0,%1,%s2,0xffff"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {rlinm.|rlwinm.} %0,%1,%s2,0xffff
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (zero_extend:SI
+         (subreg:HI
+          (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                       (match_operand:SI 2 "const_int_operand" "")) 0))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
+  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
   "{sra|sraw}%I2 %0,%1,%h2")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
-       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))
-   (clobber (match_scratch:SI 4 "=q,X"))]
+   (clobber (match_scratch:SI 3 "=r,r,r,r"))
+   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
   "TARGET_POWER"
   "@
    srea. %3,%1,%2
-   {srai.|srawi.} %3,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+   {srai.|srawi.} %3,%1,%h2
+   #
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 3)
+       (ashiftrt:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "! TARGET_POWER"
-  "{sra|sraw}%I2. %3,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {sra|sraw}%I2. %3,%1,%h2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWER && reload_completed"
+  [(set (match_dup 3)
+       (ashiftrt:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
-       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "r,i"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (ashiftrt:SI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:SI 4 "=q,X"))]
+   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
   "TARGET_POWER"
   "@
    srea. %0,%1,%2
-   {srai.|srawi.} %0,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+   {srai.|srawi.} %0,%1,%h2
+   #
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ashiftrt:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (ashiftrt:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 4))])
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ashiftrt:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWER"
-  "{sra|sraw}%I2. %0,%1,%h2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   {sra|sraw}%I2. %0,%1,%h2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
 \f
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ashiftrt:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (ashiftrt:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
 ;; Floating-point insns, excluding normal data motion.
 ;;
 ;; PowerPC has a full set of single-precision floating point instructions.
 \f
 ;; Conversions to and from floating-point.
 
+; For each of these conversions, there is a define_expand, a define_insn
+; with a '#' template, and a define_split (with C code).  The idea is
+; to allow constant folding with the template of the define_insn,
+; then to have the insns split later (between sched1 and final).
+
 (define_expand "floatsidf2"
   [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
                   (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
              (use (match_dup 3))
              (clobber (match_dup 4))
              (clobber (match_dup 5))
-             (clobber (reg:DF 76))])]
+             (clobber (match_dup 6))])]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
   "
 {
   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
   operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
-  operands[4] = gen_reg_rtx (SImode);
-  operands[5] = gen_reg_rtx (Pmode);
+  operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
+  operands[5] = gen_reg_rtx (DFmode);
+  operands[6] = gen_reg_rtx (SImode);
 }")
 
 (define_insn "*floatsidf2_internal"
        (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
-   (clobber (match_operand 5 "gpc_reg_operand" "=b"))
-   (clobber (reg:DF 76))]
+   (clobber (match_operand:DF 4 "memory_operand" "=o"))
+   (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))
+   (clobber (match_operand:SI 6 "gpc_reg_operand" "=r"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
   "#"
   [(set_attr "length" "24")])
        (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
    (use (match_operand:SI 2 "gpc_reg_operand" ""))
    (use (match_operand:DF 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:SI 4 "gpc_reg_operand" ""))
-   (clobber (match_operand 5 "gpc_reg_operand" ""))
-   (clobber (reg:DF 76))]
+   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
+   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))
+   (clobber (match_operand:SI 6 "gpc_reg_operand" ""))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
-  [(set (match_dup 4)
-       (xor:SI (match_dup 1)
-               (match_dup 6)))
-   (set (match_dup 5)
-       (unspec [(const_int 0)] 11))
-   (set (match_dup 7)
-       (unspec [(match_dup 4)
-                (match_dup 5)] 12))    ;; low word
-   (set (match_dup 7)
-       (unspec [(match_dup 2)
-                (match_dup 5)
-                (match_dup 7)] 13))    ;; high word
-   (set (match_dup 0)
-       (unspec [(match_dup 7)
-                (match_dup 5)] 14))
-   (set (match_dup 0)
-       (minus:DF (match_dup 0)
-                 (match_dup 3)))]
+  [(set (match_operand:DF 0 "gpc_reg_operand" "")
+       (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
+   (use (match_operand:SI 2 "gpc_reg_operand" ""))
+   (use (match_operand:DF 3 "gpc_reg_operand" ""))
+   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
+   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))
+   (clobber (match_operand:SI 6 "gpc_reg_operand" ""))]
   "
 {
-  operands[6] = GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff);
-  operands[7] = gen_rtx_REG (DFmode, FPMEM_REGNUM);
+  rtx lowword, highword;
+  if (GET_CODE (operands[4]) != MEM)
+    abort();
+  highword = XEXP (operands[4], 0);
+  lowword = plus_constant (highword, 4);
+  if (! WORDS_BIG_ENDIAN)
+    {
+      rtx tmp;
+      tmp = highword; highword = lowword; lowword = tmp;
+    }
+
+  emit_insn (gen_xorsi3 (operands[6], operands[1], 
+                        GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
+  emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[6]);
+  emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]);
+  emit_move_insn (operands[5], operands[4]);
+  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
+  DONE;
 }")
 
 (define_expand "floatunssidf2"
              (use (match_dup 2))
              (use (match_dup 3))
              (clobber (match_dup 4))
-             (clobber (reg:DF 76))])]
+             (clobber (match_dup 5))])]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
   "
 {
   operands[2] = force_reg (SImode, GEN_INT (0x43300000));
   operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
-  operands[4] = gen_reg_rtx (Pmode);
+  operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
+  operands[5] = gen_reg_rtx (DFmode);
 }")
 
 (define_insn "*floatunssidf2_internal"
        (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
    (use (match_operand:DF 3 "gpc_reg_operand" "f"))
-   (clobber (match_operand 4 "gpc_reg_operand" "=b"))
-   (clobber (reg:DF 76))]
+   (clobber (match_operand:DF 4 "memory_operand" "=o"))
+   (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
   "#"
   [(set_attr "length" "20")])
        (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
    (use (match_operand:SI 2 "gpc_reg_operand" ""))
    (use (match_operand:DF 3 "gpc_reg_operand" ""))
-   (clobber (match_operand 4 "gpc_reg_operand" ""))
-   (clobber (reg:DF 76))]
+   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
+   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
-  [(set (match_dup 4)
-       (unspec [(const_int 0)] 11))
-   (set (match_dup 5)
-       (unspec [(match_dup 1)
-                (match_dup 4)] 12))    ;; low word
-   (set (match_dup 5)
-       (unspec [(match_dup 2)
-                (match_dup 4)
-                (match_dup 5)] 13))    ;; high word
-   (set (match_dup 0)
-       (unspec [(match_dup 5)
-                (match_dup 4)] 14))
-   (set (match_dup 0)
-       (minus:DF (match_dup 0)
-                 (match_dup 3)))]
-  "operands[5] = gen_rtx_REG (DFmode, FPMEM_REGNUM);")
-
-;; Load up scratch register with base address + offset if needed
-(define_insn "*floatsidf2_loadaddr"
-  [(set (match_operand 0 "gpc_reg_operand" "=b")
-       (unspec [(const_int 0)] 11))]
-  "TARGET_HARD_FLOAT"
-  "*
-{
-  if (rs6000_fpmem_offset > 32760)
-    {
-      rtx xop[3];
-
-      xop[0] = operands[0];
-      xop[1] = (frame_pointer_needed) ? frame_pointer_rtx : stack_pointer_rtx;
-      xop[2] = GEN_INT ((rs6000_fpmem_offset >> 16) + ((rs6000_fpmem_offset & 0x8000) >> 15));
-      output_asm_insn (\"{cau|addis} %0,%1,%2\", xop);
-    }
-
-  return \"\";
-}"
-  [(set_attr "length" "4")])
-
-(define_insn "*floatsidf2_store1"
-  [(set (reg:DF 76)
-       (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
-                (match_operand 1 "gpc_reg_operand" "b")] 12))]
-  "TARGET_HARD_FLOAT"
-  "*
-{
-  rtx indx;
-
-  if (rs6000_fpmem_offset > 32760)
-    indx = operands[1];
-  else if (frame_pointer_needed)
-    indx = frame_pointer_rtx;
-  else
-    indx = stack_pointer_rtx;
-
-  operands[2]
-    = gen_rtx_MEM (SImode,
-                  plus_constant (indx,
-                                 (((rs6000_fpmem_offset & 0xffff) ^ 0x8000)
-                                  - 0x8000)
-                                 + ((WORDS_BIG_ENDIAN != 0) * 4)));
-
-  return \"{st|stw} %0,%2\";
-}"
-  [(set_attr "type" "store")])
-
-(define_insn "*floatsidf2_store2"
-  [(set (reg:DF 76)
-       (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
-                (match_operand 1 "gpc_reg_operand" "b")
-                (reg:DF 76)] 13))]
-  "TARGET_HARD_FLOAT"
-  "*
-{
-  rtx indx;
-
-  if (rs6000_fpmem_offset > 32760)
-    indx = operands[1];
-  else if (frame_pointer_needed)
-    indx = frame_pointer_rtx;
-  else
-    indx = stack_pointer_rtx;
-
-  operands[2]
-    = gen_rtx_MEM (SImode,
-                  plus_constant (indx,
-                                 (((rs6000_fpmem_offset & 0xffff) ^ 0x8000)
-                                  - 0x8000)
-                                 + ((WORDS_BIG_ENDIAN == 0) * 4)));
-
-  return \"{st|stw} %0,%2\";
-}"
-  [(set_attr "type" "store")])
-
-(define_insn "*floatsidf2_load"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-       (unspec [(reg:DF 76)
-                (match_operand 1 "gpc_reg_operand" "b")] 14))]
-  "TARGET_HARD_FLOAT"
-  "*
+  [(set (match_operand:DF 0 "gpc_reg_operand" "")
+       (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
+   (use (match_operand:SI 2 "gpc_reg_operand" ""))
+   (use (match_operand:DF 3 "gpc_reg_operand" ""))
+   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
+   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))]
+  "
 {
-  rtx indx;
-  HOST_WIDE_INT offset = rs6000_fpmem_offset;
-
-  if (rs6000_fpmem_offset > 32760)
+  rtx lowword, highword;
+  if (GET_CODE (operands[4]) != MEM)
+    abort();
+  highword = XEXP (operands[4], 0);
+  lowword = plus_constant (highword, 4);
+  if (! WORDS_BIG_ENDIAN)
     {
-      indx = operands[1];
-      offset = (((offset & 0xffff) ^ 0x8000) - 0x8000);
+      rtx tmp;
+      tmp = highword; highword = lowword; lowword = tmp;
     }
-  else if (frame_pointer_needed)
-    indx = frame_pointer_rtx;
-  else
-    indx = stack_pointer_rtx;
-
-  operands[2] = gen_rtx_MEM (SImode, plus_constant (indx, offset));
 
-  return \"lfd %0,%2\";
-}"
-  [(set_attr "type" "fpload")])
+  emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[1]);
+  emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]);
+  emit_move_insn (operands[5], operands[4]);
+  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
+  DONE;
+}")
 
 (define_expand "fix_truncdfsi2"
   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
                   (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
              (clobber (match_dup 2))
-             (clobber (match_dup 3))
-             (clobber (match_dup 4))])]
+             (clobber (match_dup 3))])]
   "TARGET_HARD_FLOAT"
   "
 {
     }
 
   operands[2] = gen_reg_rtx (DImode);
-  operands[3] = gen_reg_rtx (Pmode);
-  operands[4] = gen_rtx_REG (DImode, FPMEM_REGNUM);
+  operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
 }")
 
 (define_insn "*fix_truncdfsi2_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
-   (clobber (match_operand 3 "gpc_reg_operand" "=b"))
-   (clobber (reg:DI 76))]
+   (clobber (match_operand:DI 3 "memory_operand" "=o"))]
   "TARGET_HARD_FLOAT"
   "#"
-  [(set_attr "length" "12")])
+  [(set_attr "length" "16")])
 
 (define_split
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
        (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
-   (clobber (match_operand 3 "gpc_reg_operand" ""))
-   (clobber (reg:DI 76))]
+   (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))]
   "TARGET_HARD_FLOAT"
-  [(clobber (match_dup 2))
-   (set (subreg:SI (match_dup 2) 0)
-       (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
-   (set (match_dup 3)
-       (unspec [(const_int 0)] 11))
-   (set (match_dup 4)
-       (unspec [(match_dup 2)
-                (match_dup 3)] 15))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-       (unspec [(match_dup 4)
-                (match_dup 3)] 16))]
-  "operands[4] = gen_rtx_REG (DImode, FPMEM_REGNUM);")
-
-(define_insn "*fix_truncdfsi2_store"
-  [(set (reg:DI 76)
-       (unspec [(match_operand:DI 0 "gpc_reg_operand" "f")
-                (match_operand 1 "gpc_reg_operand" "b")] 15))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
-  "*
-{
-  rtx indx;
-
-  if (rs6000_fpmem_offset > 32760)
-    indx = operands[1];
-  else if (frame_pointer_needed)
-    indx = frame_pointer_rtx;
-  else
-    indx = stack_pointer_rtx;
-
-  operands[2] = gen_rtx_MEM (DFmode,
-                            plus_constant (indx,
-                                           (((rs6000_fpmem_offset & 0xffff)
-                                             ^ 0x8000) - 0x8000)));
-
-  return \"stfd %0,%2\";
-}"
-  [(set_attr "type" "fpstore")])
-
-(define_insn "*fix_truncdfsi2_load"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (unspec [(reg:DI 76)
-                (match_operand 1 "gpc_reg_operand" "b")] 16))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
-  "*
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+       (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
+   (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))]
+  "
 {
-  rtx indx;
-
-  if (rs6000_fpmem_offset > 32760)
-    indx = operands[1];
-  else if (frame_pointer_needed)
-    indx = frame_pointer_rtx;
-  else
-    indx = stack_pointer_rtx;
-
-  operands[2]
-    = gen_rtx_MEM (DFmode,
-                  plus_constant (indx,
-                                 (((rs6000_fpmem_offset & 0xffff) ^ 0x8000)
-                                  - 0x8000)
-                                 + ((WORDS_BIG_ENDIAN) ? 4 : 0)));
+  rtx lowword;
+  if (GET_CODE (operands[3]) != MEM)
+    abort();
+  lowword = XEXP (operands[3], 0);
+  if (WORDS_BIG_ENDIAN)
+    lowword = plus_constant (lowword, 4);
 
-  return \"{l|lwz} %0,%2\";
-}"
-  [(set_attr "type" "load")])
+  emit_insn (gen_fctiwz (operands[2], operands[1]));
+  emit_move_insn (operands[3], operands[2]);
+  emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword));
+  DONE;
+}")
 
 (define_expand "fixuns_truncdfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
   rs6000_trunc_used = 1;
 }")
 
-(define_insn "*fctiwz"
-  [(set (subreg:SI (match_operand:DI 0 "gpc_reg_operand" "=f") 0)
-       (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))]
+; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] 10))
+; rather than (set (subreg:SI (reg)) (fix:SI ...))
+; because the first makes it clear that operand 0 is not live
+; before the instruction.
+(define_insn "fctiwz"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
+       (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
    addis %0,%1,%v2")
 
 (define_insn "*adddi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
-       (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-                            (match_operand:DI 2 "reg_or_short_operand" "r,I"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
+                            (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
   "TARGET_POWERPC64"
   "@
    add. %3,%1,%2
-   addic. %3,%1,%2"
-  [(set_attr "type" "compare")])
+   addic. %3,%1,%2
+   #
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                            (match_operand:DI 2 "reg_or_short_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (plus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*adddi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
-       (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-                            (match_operand:DI 2 "reg_or_short_operand" "r,I"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
+       (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
+                            (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (plus:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
   "@
    add. %0,%1,%2
-   addic. %0,%1,%2"
-  [(set_attr "type" "compare")])
+   addic. %0,%1,%2
+   #
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,4,8,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (plus:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                            (match_operand:DI 2 "reg_or_short_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (plus:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (plus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; Split an add that we can't do in one insn into two insns, each of which
 ;; does one 16-bit part.  This is used by combine.  Note that the low-order
   "nor %0,%1,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "nor. %2,%1,%1"
-  [(set_attr "type" "compare")])
+  "@
+   nor. %2,%1,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (not:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (not:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "nor. %0,%1,%1"
-  [(set_attr "type" "compare")])
+  "@
+   nor. %0,%1,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (not:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (not:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
    subfic %0,%2,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                             (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                             (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "subf. %3,%2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   subf. %3,%2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                             (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (minus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                             (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                             (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (minus:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "subf. %0,%2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   subf. %0,%2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (minus:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                             (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (minus:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (minus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "subdi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
   "neg %0,%1")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r"))]
+   (clobber (match_scratch:DI 2 "=r,r"))]
   "TARGET_POWERPC64"
-  "neg. %2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   neg. %2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 2)
+       (neg:DI (match_dup 1)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (neg:DI (match_dup 1)))]
   "TARGET_POWERPC64"
-  "neg. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   neg. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (neg:DI (match_dup 1)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (neg:DI (match_dup 1)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "ffsdi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
   [(set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                           (match_operand:DI 2 "const_int_operand" "N"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:DI 2 "const_int_operand" "N,N"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
-  "sradi %3,%1,%p2\;addze. %3,%3"
+  "@
+   sradi %3,%1,%p2\;addze. %3,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:DI 2 "const_int_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
+  [(set (match_dup 3)
+       (div:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                           (match_operand:DI 2 "const_int_operand" "N"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:DI 2 "const_int_operand" "N,N"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (div:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0"
-  "sradi %0,%1,%p2\;addze. %0,%0"
+  "@
+   sradi %0,%1,%p2\;addze. %0,%0
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
 
-(define_insn ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (div:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:DI 2 "const_int_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (div:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && exact_log2 (INTVAL (operands[2])) >= 0 && reload_completed"
+  [(set (match_dup 0)
+       (div:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
+(define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
         (div:DI (match_operand:DI 1 "gpc_reg_operand" "r")
                 (match_operand:DI 2 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC64"
   "rld%I2cl %0,%1,%H2,0")
 
 (define_insn "*rotldi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                              (match_operand:DI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %3,%1,%H2,0"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %3,%1,%H2,0
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                              (match_operand:DI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (rotate:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                              (match_operand:DI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (rotate:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %0,%1,%H2,0"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %0,%1,%H2,0
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                              (match_operand:DI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (rotate:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (rotate:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal4"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "rld%I2c%B3 %0,%1,%H2,%S3")
 
 (define_insn "*rotldi3_internal5"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (and:DI
-                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                               (match_operand:DI 2 "reg_or_cint_operand" "ri"))
-                    (match_operand:DI 3 "mask64_operand" "S"))
+                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                               (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
+                    (match_operand:DI 3 "mask64_operand" "S,S"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 4 "=r"))]
+   (clobber (match_scratch:DI 4 "=r,r"))]
   "TARGET_POWERPC64"
-  "rld%I2c%B3. %4,%1,%H2,%S3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2c%B3. %4,%1,%H2,%S3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:DI
+                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                               (match_operand:DI 2 "reg_or_cint_operand" ""))
+                    (match_operand:DI 3 "mask64_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 4 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (and:DI (rotate:DI (match_dup 1)
+                               (match_dup 2))
+                    (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal6"
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC (and:DI
-                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                               (match_operand:DI 2 "reg_or_cint_operand" "ri"))
-                    (match_operand:DI 3 "mask64_operand" "S"))
+                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                               (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
+                    (match_operand:DI 3 "mask64_operand" "S,S"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "TARGET_POWERPC64"
-  "rld%I2c%B3. %0,%1,%H2,%S3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2c%B3. %0,%1,%H2,%S3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:DI
+                    (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                               (match_operand:DI 2 "reg_or_cint_operand" ""))
+                    (match_operand:DI 3 "mask64_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal7"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "rld%I2cl %0,%1,%H2,56")
 
 (define_insn "*rotldi3_internal8"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:DI
                     (subreg:QI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %3,%1,%H2,56"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %3,%1,%H2,56
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI
+                    (subreg:QI
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (zero_extend:DI (subreg:QI
+                     (rotate:DI (match_dup 1)
+                                (match_dup 2)) 0)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal9"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:DI
                     (subreg:QI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %0,%1,%H2,56"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %0,%1,%H2,56
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI
+                    (subreg:QI
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal10"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "rld%I2cl %0,%1,%H2,48")
 
 (define_insn "*rotldi3_internal11"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:DI
                     (subreg:HI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %3,%1,%H2,48"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %3,%1,%H2,48
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI
+                    (subreg:HI
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (zero_extend:DI (subreg:HI
+                     (rotate:DI (match_dup 1)
+                                (match_dup 2)) 0)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal12"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:DI
                     (subreg:HI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %0,%1,%H2,48"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %0,%1,%H2,48
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI
+                    (subreg:HI
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal13"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "rld%I2cl %0,%1,%H2,32")
 
 (define_insn "*rotldi3_internal14"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:DI
                     (subreg:SI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %3,%1,%H2,32"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %3,%1,%H2,32
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI
+                    (subreg:SI
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (zero_extend:DI (subreg:SI
+                     (rotate:DI (match_dup 1)
+                                (match_dup 2)) 0)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*rotldi3_internal15"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC (zero_extend:DI
                     (subreg:SI
-                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0))
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
   "TARGET_POWERPC64"
-  "rld%I2cl. %0,%1,%H2,32"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rld%I2cl. %0,%1,%H2,32
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (zero_extend:DI
+                    (subreg:SI
+                     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "ashldi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
   [(set_attr "length" "8")])
   
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "sld%I2. %3,%1,%H2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   sld%I2. %3,%1,%H2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
   
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (ashift:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
+
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                              (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                              (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (ashift:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "sld%I2. %0,%1,%H2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   sld%I2. %0,%1,%H2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                              (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (ashift:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ashift:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "rldic %0,%1,%H2,%S3")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                           (match_operand:SI 2 "const_int_operand" "i"))
-                (match_operand:DI 3 "mask64_operand" "S"))
+        (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:SI 2 "const_int_operand" "i,i"))
+                (match_operand:DI 3 "mask64_operand" "S,S"))
         (const_int 0)))
-   (clobber (match_scratch:DI 4 "=r"))]
+   (clobber (match_scratch:DI 4 "=r,r"))]
   "((GET_CODE (operands[3]) == CONST_INT
      ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1"
-  "rldic. %0,%1,%H2,%S3"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   rldic. %0,%1,%H2,%S3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:SI 2 "const_int_operand" ""))
+                (match_operand:DI 3 "mask64_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:DI 4 ""))]
+  "((GET_CODE (operands[3]) == CONST_INT
+     ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1
+   && reload_completed"
+  [(set (match_dup 4)
+       (and:DI (ashift:DI (match_dup 1) (match_dup 2))
+                (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                           (match_operand:SI 2 "const_int_operand" "i"))
-                (match_operand:DI 3 "mask64_operand" "S"))
+        (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                           (match_operand:SI 2 "const_int_operand" "i,i"))
+                (match_operand:DI 3 "mask64_operand" "S,S"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
   "((GET_CODE (operands[3]) == CONST_INT
      ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1"
-  "rldic. %0,%1,%H2,%S3"
-  [(set_attr "type" "delayed_compare")])
-
-(define_expand "lshrdi3"
+  "@
+   rldic. %0,%1,%H2,%S3
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:SI 2 "const_int_operand" ""))
+                (match_operand:DI 3 "mask64_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+  "((GET_CODE (operands[3]) == CONST_INT
+     ? INTVAL (operands[3]) : CONST_DOUBLE_LOW (operands[3])) & 1) == 1
+   && reload_completed"
+  [(set (match_dup 0)
+       (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
+(define_expand "lshrdi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
                     (match_operand:SI 2 "reg_or_cint_operand" "")))]
   "srd%I2 %0,%1,%H2")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "srd%I2. %3,%1,%H2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   srd%I2. %3,%1,%H2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (lshiftrt:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (lshiftrt:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "srd%I2. %0,%1,%H2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   srd%I2. %0,%1,%H2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (lshiftrt:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (lshiftrt:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "ashrdi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
   "srad%I2 %0,%1,%H2")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "srad%I2. %3,%1,%H2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   srad%I2. %3,%1,%H2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (ashiftrt:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                                (match_operand:SI 2 "reg_or_cint_operand" "ri"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                                (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "srad%I2. %0,%1,%H2"
-  [(set_attr "type" "delayed_compare")])
+  "@
+   srad%I2. %0,%1,%H2
+   #"
+  [(set_attr "type" "delayed_compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                (match_operand:SI 2 "reg_or_cint_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (ashiftrt:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ashiftrt:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "anddi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
    andis. %0,%1,%u2")
 
 (define_insn "*anddi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
-       (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
-                           (match_operand:DI 2 "and64_operand" "r,K,J,S"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
+       (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,")
+                           (match_operand:DI 2 "and64_operand" "r,K,J,S,r,K,J,S"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r,r,r"))]
+   (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r"))
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
   "TARGET_POWERPC64"
   "@
    and. %3,%1,%2
    andi. %3,%1,%b2
    andis. %3,%1,%u2
-   rldic%B2. %3,%1,0,%S2"
-  [(set_attr "type" "compare,compare,compare,delayed_compare")])
+   rldic%B2. %3,%1,0,%S2
+   #
+   #
+   #
+   #"
+  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,delayed_compare")
+   (set_attr "length" "4,4,4,4,8,8,8,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+        (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                            (match_operand:DI 2 "and64_operand" ""))
+                    (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))
+   (clobber (match_scratch:CC 4 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 3)
+                   (and:DI (match_dup 1)
+                           (match_dup 2)))
+              (clobber (match_dup 4))])
+   (set (match_dup 0)
+        (compare:CC (match_dup 3)
+                    (const_int 0)))]
+  "")
 
 (define_insn "*anddi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x")
-       (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r")
-                           (match_operand:DI 2 "and64_operand" "r,K,J,S"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
+       (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
+                           (match_operand:DI 2 "and64_operand" "r,K,J,S,r,K,J,S"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
-       (and:DI (match_dup 1) (match_dup 2)))]
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r")
+       (and:DI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
   "TARGET_POWERPC64"
   "@
    and. %0,%1,%2
    andi. %0,%1,%b2
    andis. %0,%1,%u2
-   rldic%B2. %0,%1,0,%S2"
-  [(set_attr "type" "compare,compare,compare,delayed_compare")])
+   rldic%B2. %0,%1,0,%S2
+   #
+   #
+   #
+   #"
+  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,delayed_compare")
+   (set_attr "length" "4,4,4,4,8,8,8,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:DI 2 "and64_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (and:DI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:CC 4 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+                   (and:DI (match_dup 1) (match_dup 2)))
+              (clobber (match_dup 4))])
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_expand "iordi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "reg_or_cint_operand" "")))]
+               (match_operand:DI 2 "reg_or_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   "
 {
   if (GET_CODE (operands[2]) == CONST_INT
-      && ! logical_operand (operands[2], DImode))
+      && ! logical_u_operand (operands[2], DImode))
     {
       HOST_WIDE_INT value = INTVAL (operands[2]);
       rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
       emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
       DONE;
     }
+  else if (GET_CODE (operands[2]) == CONST_DOUBLE
+      && ! logical_u_operand (operands[2], DImode))
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+                ? operands[0] : gen_reg_rtx (DImode));
+
+      emit_insn (gen_iordi3 (tmp, operands[1],
+                            immed_double_const (value
+                                                & (~ (HOST_WIDE_INT) 0xffff),
+                                                0, DImode)));
+      emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+      DONE;
+    }
 }")
 
 (define_insn "*iordi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
        (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
-               (match_operand:DI 2 "logical_operand" "r,K,J")))]
+               (match_operand:DI 2 "logical_u_operand" "r,K,JF")))]
   "TARGET_POWERPC64"
   "@
    or %0,%1,%2
    oris %0,%1,%u2")
 
 (define_insn "*iordi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "or. %3,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   or. %3,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (ior:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*iordi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (ior:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "or. %0,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   or. %0,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (ior:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ior:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; Split an IOR that we can't do in one insn into two insns, each of which
 ;; does one 16-bit part.  This is used by combine.
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "non_logical_cint_operand" "")))]
+               (match_operand:DI 2 "non_logical_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3)))
    (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))]
 "
 {
-  operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
-  operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+  if (GET_CODE (operands[2]) == CONST_DOUBLE)
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff),
+                                       0, DImode);
+      operands[4] = GEN_INT (value & 0xffff);
+    }
+  else
+    {
+      operands[3] = GEN_INT (INTVAL (operands[2])
+                            & (~ (HOST_WIDE_INT) 0xffff));
+      operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+    }
 }")
 
 (define_expand "xordi3"
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
-               (match_operand:DI 2 "reg_or_cint_operand" "")))]
+               (match_operand:DI 2 "reg_or_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   "
 {
   if (GET_CODE (operands[2]) == CONST_INT
-      && ! logical_operand (operands[2], DImode))
+      && ! logical_u_operand (operands[2], DImode))
     {
       HOST_WIDE_INT value = INTVAL (operands[2]);
       rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
       emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
       DONE;
     }
+  else if (GET_CODE (operands[2]) == CONST_DOUBLE
+      && ! logical_u_operand (operands[2], DImode))
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
+                ? operands[0] : gen_reg_rtx (DImode));
+
+      emit_insn (gen_xordi3 (tmp, operands[1],
+                            immed_double_const (value
+                                                & (~ (HOST_WIDE_INT) 0xffff),
+                                                0, DImode)));
+      emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
+      DONE;
+    }
 }")
 
 (define_insn "*xordi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
        (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
-               (match_operand:DI 2 "logical_operand" "r,K,J")))]
+               (match_operand:DI 2 "logical_u_operand" "r,K,JF")))]
   "TARGET_POWERPC64"
   "@
    xor %0,%1,%2
    xoris %0,%1,%u2")
 
 (define_insn "*xordi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "xor. %3,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   xor. %3,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (xor:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*xordi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (xor:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "xor. %0,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   xor. %0,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (xor:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (xor:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; Split an XOR that we can't do in one insn into two insns, each of which
 ;; does one 16-bit part.  This is used by combine.
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
         (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
-                (match_operand:DI 2 "non_logical_cint_operand" "")))]
+                (match_operand:DI 2 "non_logical_u_cint_operand" "")))]
   "TARGET_POWERPC64"
   [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3)))
    (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))]
 "
 {
-  operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
-  operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+  if (GET_CODE (operands[2]) == CONST_DOUBLE)
+    {
+      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
+      operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff),
+                                       0, DImode);
+      operands[4] = GEN_INT (value & 0xffff);
+    }
+  else
+    {
+      operands[3] = GEN_INT (INTVAL (operands[2])
+                            & (~ (HOST_WIDE_INT) 0xffff));
+      operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff);
+    }
 }")
 
 (define_insn "*eqvdi3_internal1"
    "eqv %0,%1,%2")
 
 (define_insn "*eqvdi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-                                   (match_operand:DI 2 "gpc_reg_operand" "r")))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+                                   (match_operand:DI 2 "gpc_reg_operand" "r,r")))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
    "TARGET_POWERPC64"
-   "eqv. %3,%1,%2"
-   [(set_attr "type" "compare")])
+   "@
+    eqv. %3,%1,%2
+    #"
+   [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                   (match_operand:DI 2 "gpc_reg_operand" "")))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+   "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (not:DI (xor:DI (match_dup 1) (match_dup 2))))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*eqvdi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
-                                   (match_operand:DI 2 "gpc_reg_operand" "r")))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+                                   (match_operand:DI 2 "gpc_reg_operand" "r,r")))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
    "TARGET_POWERPC64"
-   "eqv. %0,%1,%2"
-   [(set_attr "type" "compare")])
-
-(define_insn "*andcdi3_internal1"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   "@
+    eqv. %0,%1,%2
+    #"
+   [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (not:DI (xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                                   (match_operand:DI 2 "gpc_reg_operand" "")))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
+   "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (not:DI (xor:DI (match_dup 1) (match_dup 2))))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
+(define_insn "*andcdi3_internal1"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
        (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
                (match_operand:DI 2 "gpc_reg_operand" "r")))]
   "TARGET_POWERPC64"
   "andc %0,%2,%1")
 
 (define_insn "*andcdi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "andc. %3,%2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   andc. %3,%2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (and:DI (not:DI (match_dup 1)) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*andcdi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "andc. %0,%2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   andc. %0,%2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (and:DI (not:DI (match_dup 1)) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (and:DI (not:DI (match_dup 1)) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*iorcdi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "orc %0,%2,%1")
 
 (define_insn "*iorcdi3_inernal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "orc. %3,%2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   orc. %3,%2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (ior:DI (not:DI (match_dup 1)) (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*iorcdi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
-                           (match_operand:DI 2 "gpc_reg_operand" "r"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
+                           (match_operand:DI 2 "gpc_reg_operand" "r,r"))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "orc. %0,%2,%1"
-  [(set_attr "type" "compare")])
+  "@
+   orc. %0,%2,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (match_operand:DI 2 "gpc_reg_operand" ""))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (ior:DI (not:DI (match_dup 1)) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ior:DI (not:DI (match_dup 1)) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*nanddi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "nand %0,%1,%2")
 
 (define_insn "*nanddi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
-                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r")))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "nand. %3,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   nand. %3,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "")))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*nanddi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
-                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r")))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
   "TARGET_POWERPC64"
-  "nand. %0,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   nand. %0,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (ior:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "")))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ior:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*nordi3_internal1"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
   "nor %0,%1,%2")
 
 (define_insn "*nordi3_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
-                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r")))
                    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r"))]
+   (clobber (match_scratch:DI 3 "=r,r"))]
   "TARGET_POWERPC64"
-  "nor. %3,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   nor. %3,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "")))
+                   (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn "*nordi3_internal3"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r"))
-                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r")))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r")))
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
   "TARGET_POWERPC64"
-  "nor. %0,%1,%2"
-  [(set_attr "type" "compare")])
+  "@
+   nor. %0,%1,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
 \f
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC (and:DI (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                           (not:DI (match_operand:DI 2 "gpc_reg_operand" "")))
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (and:DI (not:DI (match_dup 1)) (not:DI (match_dup 2))))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
 ;; Now define ways of moving data around.
 
 ;; Elf specific ways of loading addresses for non-PIC code.
-;; The output of this could be r0, but we limit it to base
-;; registers, since almost all uses of this will need it
-;; in a base register shortly.
+;; The output of this could be r0, but we make a very strong
+;; preference for a base register because it will usually
+;; be needed there.
 (define_insn "elf_high"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
        (high:SI (match_operand 1 "" "")))]
   "TARGET_ELF && ! TARGET_64BIT"
   "{liu|lis} %0,%1@ha")
 
 (define_insn "elf_low"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
                   (match_operand 2 "" "")))]
    "TARGET_ELF && ! TARGET_64BIT"
-   "{cal|la} %0,%2@l(%1)")
+   "@
+    {cal|la} %0,%2@l(%1)
+    {ai|addic} %0,%1,%l2")
 
 ;; Set up a register with a value from the GOT table
 
 (define_expand "movsi_got"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
-       (unspec [(match_operand:SI 1 "got_operand" "")
-                (match_dup 2)] 8))]
+       (unspec:SI [(match_operand:SI 1 "got_operand" "")
+                   (match_dup 2)] 8))]
   "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
   "
 {
 
 (define_insn "*movsi_got_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (unspec [(match_operand:SI 1 "got_no_const_operand" "")
-                (match_operand:SI 2 "gpc_reg_operand" "b")] 8))]
+       (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
+                   (match_operand:SI 2 "gpc_reg_operand" "b")] 8))]
   "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
   "{l|lwz} %0,%a1@got(%2)"
   [(set_attr "type" "load")])
 ;; didn't get allocated to a hard register.
 (define_split 
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (unspec [(match_operand:SI 1 "got_no_const_operand" "")
-                (match_operand:SI 2 "memory_operand" "m")] 8))]
+       (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
+                   (match_operand:SI 2 "memory_operand" "m")] 8))]
   "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
     && flag_pic == 1
     && (reload_in_progress || reload_completed)"
   [(set (match_dup 0) (match_dup 2))
-   (set (match_dup 0) (unspec [(match_dup 1)(match_dup 0)] 8))]
+   (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 8))]
   "")
 
 ;; For SI, we special-case integers that can't be loaded in one insn.  We
   ""
   "
 {
-  if (GET_CODE (operands[0]) != REG)
+  if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
     operands[1] = force_reg (SImode, operands[1]);
 
   /* Convert a move of a CONST_DOUBLE into a CONST_INT */
     {
       rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (SImode));
 
-      /* If this is a function address on -mcall-aixdesc or -mcall-nt,
+      /* If this is a function address on -mcall-aixdesc,
         convert it to the address of the descriptor.  */
-      if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+      if (DEFAULT_ABI == ABI_AIX
          && GET_CODE (operands[1]) == SYMBOL_REF
          && XSTR (operands[1], 0)[0] == '.')
        {
-         const char *name = XSTR (operands[1], 0);
+         char *name = XSTR (operands[1], 0);
          rtx new_ref;
          while (*name == '.')
            name++;
       DONE;
     }
 
-  if (GET_CODE (operands[1]) == CONST
-      && DEFAULT_ABI == ABI_NT
-      && ! side_effects_p (operands[0]))
-    {
-      rtx const_term = const0_rtx;
-      rtx sym = eliminate_constant_term (XEXP (operands[1], 0), &const_term);
-      if (sym && GET_CODE (const_term) == CONST_INT
-         && (GET_CODE (sym) == SYMBOL_REF || GET_CODE (sym) == LABEL_REF))
-       {
-         unsigned HOST_WIDE_INT value = INTVAL (const_term);
-         int new_reg_p = (flag_expensive_optimizations && ! no_new_pseudos);
-         rtx tmp1 = ((new_reg_p && value != 0)
-                     ? gen_reg_rtx (SImode) : operands[0]);
-
-         emit_insn (gen_movsi (tmp1, sym));
-         if (INTVAL (const_term) != 0)
-           emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
-         DONE;
-       }
-      else
-       rs6000_fatal_bad_address (operands[1]);
-    }
-
-  if ((! TARGET_WINDOWS_NT || DEFAULT_ABI != ABI_NT)
-      && CONSTANT_P (operands[1])
+  if (CONSTANT_P (operands[1])
       && GET_CODE (operands[1]) != CONST_INT
       && GET_CODE (operands[1]) != HIGH
-      && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
+      && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
+      && ! TOC_RELATIVE_EXPR_P (operands[1]))
     {
       /* Emit a USE operation so that the constant isn't deleted if
         expensive optimizations are turned on because nobody
        }
 
       operands[1] = force_const_mem (SImode, operands[1]);
+
+      if (TARGET_TOC 
+         && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
+         && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (
+               XEXP (operands[1], 0))))
+       {
+         XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0));
+         MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set ();   
+         RTX_UNCHANGING_P (operands[1]) = 1;
+       }
+
       if (! memory_address_p (SImode, XEXP (operands[1], 0))
          && ! reload_in_progress)
        operands[1] = change_address (operands[1], SImode,
 }")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r,r")
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 1))]
   "! TARGET_POWERPC64"
-  "mr. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   mr. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
 \f
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 1))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0) (match_dup 1))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
 (define_expand "movhi"
   [(set (match_operand:HI 0 "general_operand" "")
        (match_operand:HI 1 "any_operand" ""))]
   ""
   "
 {
-  if (GET_CODE (operands[0]) != REG)
+  if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
     operands[1] = force_reg (HImode, operands[1]);
 
   if (CONSTANT_P (operands[1])
   ""
   "
 {
-  if (GET_CODE (operands[0]) != REG)
+  if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
     operands[1] = force_reg (QImode, operands[1]);
 
   if (CONSTANT_P (operands[1])
   ""
   "
 {
-  if (GET_CODE (operands[0]) != REG)
+  if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
     operands[1] = force_reg (DImode, operands[1]);
 
   /* Convert a move of a CONST_DOUBLE into a CONST_INT
       && GET_CODE (operands[1]) != CONST_INT
 #endif
       && ! easy_fp_constant (operands[1], DImode)
-      && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1]))
+      && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
+      && ! TOC_RELATIVE_EXPR_P (operands[1]))
     {
       /* Emit a USE operation so that the constant isn't deleted if
         expensive optimizations are turned on because nobody
        }
 
       operands[1] = force_const_mem (DImode, operands[1]);
+      if (TARGET_TOC && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)))
+       {
+         XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0));
+         MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set ();   
+         RTX_UNCHANGING_P (operands[1]) = 1;
+       }       
       if (! memory_address_p (DImode, XEXP (operands[1], 0))
          && ! reload_in_progress)
        operands[1] = change_address (operands[1], DImode,
                                      XEXP (operands[1], 0));
     }
+
+  if (TARGET_TOC 
+     && GET_CODE (operands[1]) == MEM 
+     && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
+    {
+      XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0));
+      MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set ();      
+      RTX_UNCHANGING_P (operands[1]) = 1;
+    }
+
 }")
 
 (define_insn "*movdi_32"
    (set (match_dup 0)
        (zero_extend:DI (subreg:SI (match_dup 0) 0)))]
   "
-{ operands[2] = GEN_INT ((INTVAL (operands[1]) << 32) >> 32); }")
+{
+#if HOST_BITS_PER_WIDE_INT != 32
+operands[2] = GEN_INT ((INTVAL (operands[1]) << 32) >> 32);
+#endif
+}")
 
 ;; 32-bit value in upper half of doubleword
 (define_split
        (match_operand:DI 1 "const_int_operand" ""))]
   "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64
    && GET_CODE (operands[1]) == CONST_INT
-   && INTVAL (operands[1]) & 0xffffffff == 0"
+   && (INTVAL (operands[1]) & 0xffffffff) == 0"
   [(set (match_dup 0)
        (match_dup 2))
    (set (match_dup 0)
        (ashift:DI (match_dup 0)
                   (const_int 32)))]
   "
-{ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); }")
+{
+#if HOST_BITS_PER_WIDE_INT != 32
+operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
+#endif
+}")
 
 ;; Generate all one-bits and clear left or right.
 ;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
   if (GET_CODE (operands[1]) == CONST_DOUBLE)
     {
       operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
-      operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
+      operands[3] = immed_double_const (CONST_DOUBLE_LOW (operands[1]),
+                                       0, DImode);
     }
   else
     {
       HOST_WIDE_INT value = INTVAL (operands[1]);
       operands[2] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
-      operands[3] = operands[1];
+      operands[3] = immed_double_const (value, 0, DImode);
     }
 }")
 
                (match_dup 3)))]
   "
 {
+#if HOST_BITS_PER_WIDE_INT != 32
   HOST_WIDE_INT value = INTVAL (operands[1]);
   operands[2] = GEN_INT (value >> 32);
   operands[3] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000));
+#endif
 }")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
-       (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r")
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+       (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r")
                    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r") (match_dup 1))]
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 1))]
   "TARGET_POWERPC64"
-  "mr. %0,%1"
-  [(set_attr "type" "compare")])
+  "@
+   mr. %0,%1
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "4,8")])
 \f
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC (match_operand:DI 1 "gpc_reg_operand" "")
+                   (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "") (match_dup 1))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0) (match_dup 1))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
 ;; TImode is similar, except that we usually want to compute the address into
 ;; a register and use lsi/stsi (the exception is during reload).  MQ is also
 ;; clobbered in stsi for POWER, so we need a SCRATCH for it.
       emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
     }
 
-  /* Under Windows NT, we need to add stack probes for large/variable
-     allocations, so do it via a call to the external function alloca
-     instead of doing it inline.  */
-  if (DEFAULT_ABI == ABI_NT
-      && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 4096))
-    {
-      rtx tmp = gen_reg_rtx (Pmode);
-      emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode,
-                                       \"__allocate_stack\"),
-                              tmp, 0, Pmode, 1, operands[1], Pmode);
-      emit_insn (gen_set_sp (tmp));
-      emit_move_insn (operands[0], tmp);
-      DONE;
-    }
-
   if (GET_CODE (operands[1]) != CONST_INT
       || INTVAL (operands[1]) < -32767
       || INTVAL (operands[1]) > 32768)
   DONE;
 }")
 
-;; Marker to indicate that the stack pointer was changed under NT in
-;; ways not known to the compiler
-
-(define_insn "set_sp"
-  [(set (reg:SI 1)
-       (unspec [(match_operand:SI 0 "register_operand" "r")] 7))]
-  ""
-  ""
-  [(set_attr "length" "0")])
-
 ;; These patterns say how to save and restore the stack pointer.  We need not
 ;; save the stack pointer at function level since we are careful to
 ;; preserve the backchain.  At block level, we have to restore the backchain
   emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
   DONE;
 }")
+\f
+;; TOC register handling.
 
-;; If we have -mminimal-toc, we need to reload r30 after a nonlocal goto.
+;; Code to initialize the TOC register...
 
-(define_insn "nonlocal_goto_receiver"
-  [(unspec_volatile [(const_int 0)] 1)]
-  "TARGET_TOC && TARGET_MINIMAL_TOC"
+(define_insn "load_toc_aix_si"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(const_int 0)] 7))]
+  "! TARGET_ELF && TARGET_32BIT"
   "*
 {
-  rs6000_output_load_toc_table (asm_out_file, 30);
-  return \"\";
+  char buf[30];
+  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
+  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
+  operands[2] = gen_rtx_REG (Pmode, 2);
+  return \"{l|lwz} %0,%1(%2)\";
 }"
   [(set_attr "type" "load")])
-\f
-;; A function pointer under AIX is a pointer to a data area whose first word
-;; contains the actual address of the function, whose second word contains a
+
+(define_insn "load_toc_aix_di"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(const_int 0)] 7))]
+  "! TARGET_ELF && TARGET_64BIT"
+  "*
+{
+  char buf[30];
+  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
+  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
+  operands[2] = gen_rtx_REG (Pmode, 2);
+  return \"ld %0,%1(%2)\";
+}"
+  [(set_attr "type" "load")])
+
+(define_insn "load_toc_v4_pic_si"
+  [(set (match_operand:SI 0 "register_operand" "=l")
+       (unspec:SI [(const_int 0)] 7))]
+  "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1
+   && TARGET_32BIT"
+  "bl _GLOBAL_OFFSET_TABLE_@local-4"
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
+
+(define_insn "load_toc_v4_pic_di"
+  [(set (match_operand:DI 0 "register_operand" "=l")
+       (unspec:DI [(const_int 0)] 7))]
+  "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1
+   && TARGET_64BIT"
+  "bl _GLOBAL_OFFSET_TABLE_@local-4"
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
+
+(define_insn "load_toc_v4_PIC_1"
+  [(set (match_operand:SI 0 "register_operand" "=l")
+       (match_operand:SI 1 "immediate_operand" "s"))
+   (unspec [(match_dup 1)] 7)]
+  "TARGET_ELF && flag_pic == 2"
+  "bl %1\\n%1:"
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
+
+(define_insn "load_toc_v4_PIC_1b"
+  [(set (match_operand:SI 0 "register_operand" "=l")
+       (match_operand:SI 1 "immediate_operand" "s"))
+   (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] 6)]
+  "TARGET_ELF && flag_pic == 2"
+  "bl %1\\n\\t.long %2-%1+4\\n%1:"
+  [(set_attr "type" "branch")
+   (set_attr "length" "8")])
+
+(define_insn "load_toc_v4_PIC_2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+                  (minus:SI (match_operand:SI 2 "immediate_operand" "s")
+                            (match_operand:SI 3 "immediate_operand" "s")))))]
+  "TARGET_ELF && flag_pic == 2"
+  "{l|lwz} %0,%2-%3(%1)"
+  [(set_attr "type" "load")])
+
+;; If the TOC is shared over a translation unit, as happens with all
+;; the kinds of PIC that we support, we need to restore the TOC
+;; pointer only when jumping over units of translation.
+
+(define_expand "builtin_setjmp_receiver"
+  [(use (label_ref (match_operand 0 "" "")))]
+  "((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1)
+   || (TARGET_TOC && TARGET_MINIMAL_TOC)"
+  "
+{
+  rs6000_emit_load_toc_table (FALSE);
+  DONE;
+}")
+\f
+;; A function pointer under AIX is a pointer to a data area whose first word
+;; contains the actual address of the function, whose second word contains a
 ;; pointer to its TOC, and whose third word contains a value to place in the
 ;; static chain register (r11).  Note that if we load the static chain, our
 ;; "trampoline" need not have any executable code.
   [(set_attr "type" "load")
    (set_attr "length" "28")])
 
-;; A function pointer undef NT is a pointer to a data area whose first word
-;; contains the actual address of the function, whose second word contains a
-;; pointer to its TOC.  The static chain is not stored under NT, which means
-;; that we need a trampoline.
-;;
-;; operands[0] is an SImode pseudo in which we place the address of the function.
-;; operands[1] is the stack size to clean up
-;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for NT)
-;; operands[3] is location to store the TOC
-;; operands[4] is the TOC register
-;;
-;; We do not break this into separate insns, so that the scheduler will not try
-;; to move the load of the new TOC before any loads from the TOC.
-
-(define_insn "call_indirect_nt"
-  [(call (mem:SI (match_operand:SI 0 "gpc_reg_operand" "b"))
-        (match_operand 1 "const_int_operand" "n"))
-   (use (match_operand 2 "const_int_operand" "n"))
-   (use (match_operand 3 "offsettable_mem_operand" "o"))
-   (use (match_operand 4 "gpc_reg_operand" "r"))
-   (clobber (match_scratch:SI 5 "=&r"))
-   (clobber (match_scratch:SI 6 "=l"))]
-  "DEFAULT_ABI == ABI_NT
-   && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
-  "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
-  [(set_attr "type" "load")
-   (set_attr "length" "24")])
-
-(define_insn "call_value_indirect_nt"
-  [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
-             (match_operand 2 "const_int_operand" "n")))
-   (use (match_operand 3 "const_int_operand" "n"))
-   (use (match_operand 4 "offsettable_mem_operand" "o"))
-   (use (match_operand 5 "gpc_reg_operand" "r"))
-   (clobber (match_scratch:SI 6 "=&r"))
-   (clobber (match_scratch:SI 7 "=l"))]
-  "DEFAULT_ABI == ABI_NT
-   && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
-  "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
-  [(set_attr "type" "load")
-   (set_attr "length" "24")])
-
 ;; A function pointer under System V is just a normal pointer
 ;; operands[0] is the function pointer
 ;; operands[1] is the stack size to clean up
 
   operands[0] = XEXP (operands[0], 0);
 
-  /* Convert NT DLL imports into an indirect call.  */
-  if (GET_CODE (operands[0]) == SYMBOL_REF
-      && (INTVAL (operands[2]) & CALL_NT_DLLIMPORT) != 0)
-    {
-      operands[0] = rs6000_dll_import_ref (operands[0]);
-      operands[2] = GEN_INT ((int)CALL_NORMAL);
-    }
-
   if (GET_CODE (operands[0]) != SYMBOL_REF
       || (INTVAL (operands[2]) & CALL_LONG) != 0)
     {
                                                         operands[1], operands[2],
                                                         toc_addr, toc_reg, static_chain));
            }
-         else if (DEFAULT_ABI == ABI_NT)
-           {
-             /* NT function pointers are really pointers to a two word area */
-             emit_call_insn (gen_call_indirect_nt (force_reg (Pmode, operands[0]),
-                                                   operands[1], operands[2],
-                                                   toc_addr, toc_reg));
-           }
          else
            abort ();
        }
 
   operands[1] = XEXP (operands[1], 0);
 
-  /* Convert NT DLL imports into an indirect call.  */
-  if (GET_CODE (operands[1]) == SYMBOL_REF
-      && (INTVAL (operands[3]) & CALL_NT_DLLIMPORT) != 0)
-    {
-      operands[1] = rs6000_dll_import_ref (operands[1]);
-      operands[3] = GEN_INT ((int)CALL_NORMAL);
-    }
-
   if (GET_CODE (operands[1]) != SYMBOL_REF
       || (INTVAL (operands[3]) & CALL_LONG) != 0)
     {
                                                               operands[2], operands[3],
                                                               toc_addr, toc_reg, static_chain));
            }
-         else if (DEFAULT_ABI == ABI_NT)
-           {
-             /* NT function pointers are really pointers to a two word area */
-             emit_call_insn (gen_call_value_indirect_nt (operands[0],
-                                                         force_reg (Pmode, operands[1]),
-                                                         operands[2], operands[3],
-                                                         toc_addr, toc_reg));
-           }
          else
            abort ();
        }
         (match_operand 1 "" "fg,fg"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (clobber (match_scratch:SI 3 "=l,l"))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+  "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
 {
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
+  return \"bl %z0\;%.\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "8,12")])
         (match_operand 1 "" "fg,fg"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (clobber (match_scratch:SI 3 "=l,l"))]
-  "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+  "TARGET_64BIT 
+   && DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
 {
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
+  return \"bl %z0\;%.\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "8,12")])
              (match_operand 2 "" "fg,fg")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (clobber (match_scratch:SI 4 "=l,l"))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+  "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
 {
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
+  return \"bl %z1\;%.\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "8,12")])
              (match_operand 2 "" "fg,fg")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (clobber (match_scratch:SI 4 "=l,l"))]
-  "TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
+  "TARGET_64BIT 
+   && DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
 {
   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
+  return \"bl %z1\;%.\";
 }"
   [(set_attr "type" "branch")
    (set_attr "length" "8,12")])
   [(unspec_volatile [(const_int 0)] 0)]
   ""
   "")
-
-;; V.4 specific code to initialize the PIC register
-
-(define_insn "init_v4_pic"
-  [(set (match_operand:SI 0 "register_operand" "=l")
-       (unspec [(const_int 0)] 7))]
-  "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS"
-  "bl _GLOBAL_OFFSET_TABLE_@local-4"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
-
 \f
 ;; Compare insns are next.  Note that the RS/6000 has two types of compares,
 ;; signed & unsigned, and one type of branch.
        (eq:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
+{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
   operands[1] = gen_rtx_COMPARE (mode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (mode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_EQ (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 (define_expand "sne"
   operands[1] = gen_rtx_COMPARE (CCFPmode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (CCFPmode);
+
+  if (TARGET_POWERPC64)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_NE (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 ;; A > 0 is best done using the portable sequence, so fail in that case.
        (gt:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
+{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
 
   if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
     FAIL;
   operands[1] = gen_rtx_COMPARE (mode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (mode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_GT (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 ;; A < 0 is best done in the portable way for A an integer.
        (lt:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
+{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
 
   if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
     FAIL;
   operands[1] = gen_rtx_COMPARE (mode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (mode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_LT (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 (define_expand "sge"
        (ge:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
+{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
   operands[1] = gen_rtx_COMPARE (mode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (mode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_GE (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 ;; A <= 0 is best done the portable way for A an integer.
        (le:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ enum machine_mode mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
+{ enum machine_mode op_mode, mode = rs6000_compare_fp_p ? CCFPmode : CCmode;
 
   if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
     FAIL;
   operands[1] = gen_rtx_COMPARE (mode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (mode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_LE (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 (define_expand "sgtu"
        (gtu:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ operands[1] = gen_rtx_COMPARE (CCUNSmode,
+{ enum machine_mode op_mode;
+
+  operands[1] = gen_rtx_COMPARE (CCUNSmode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (CCUNSmode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && op_mode == DImode)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_GTU (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 (define_expand "sltu"
        (ltu:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ operands[1] = gen_rtx_COMPARE (CCUNSmode,
+{ enum machine_mode op_mode;
+
+  operands[1] = gen_rtx_COMPARE (CCUNSmode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (CCUNSmode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && op_mode == DImode)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_LTU (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 (define_expand "sgeu"
        (geu:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ operands[1] = gen_rtx_COMPARE (CCUNSmode,
+{ enum machine_mode op_mode;
+
+  operands[1] = gen_rtx_COMPARE (CCUNSmode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (CCUNSmode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && op_mode == DImode)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_GEU (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 
 (define_expand "sleu"
        (leu:SI (match_dup 2) (const_int 0)))]
   ""
   "
-{ operands[1] = gen_rtx_COMPARE (CCUNSmode,
+{ enum machine_mode op_mode;
+
+  operands[1] = gen_rtx_COMPARE (CCUNSmode,
                                 rs6000_compare_op0, rs6000_compare_op1);
   operands[2] = gen_reg_rtx (CCUNSmode);
+
+  op_mode = GET_MODE (rs6000_compare_op0);
+  if (op_mode == VOIDmode)
+    op_mode = GET_MODE (rs6000_compare_op1);
+
+  if (TARGET_POWERPC64 && op_mode == DImode)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+      convert_move (operands[0],
+                   gen_rtx_LEU (DImode, operands[2], const0_rtx), 0);
+      DONE;
+    }
 }")
 \f
 ;; Here are the actual compare insns.
 (define_insn ""
   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
        (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
-                      (match_operand:SI 2 "reg_or_u_short_operand" "rI")))]
+                      (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
   ""
   "{cmpl%I2|cmplw%I2} %0,%1,%W2"
   [(set_attr "type" "compare")])
 (define_insn ""
   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
        (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
-                      (match_operand:DI 2 "reg_or_u_short_operand" "rI")))]
+                      (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
   ""
   "cmpld%I2 %0,%1,%W2"
   [(set_attr "type" "compare")])
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (match_operator:DI 1 "scc_comparison_operator"
+                          [(match_operand 2 "cc_reg_operand" "y")
+                           (const_int 0)]))]
+  "TARGET_POWERPC64"
+  "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
+  [(set_attr "length" "12")])
+
+(define_insn ""
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC (match_operator:SI 1 "scc_comparison_operator"
-                                      [(match_operand 2 "cc_reg_operand" "y")
+                                      [(match_operand 2 "cc_reg_operand" "y,y")
                                        (const_int 0)])
                    (const_int 0)))
-   (set (match_operand:SI 3 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
        (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
   "! TARGET_POWERPC64"
-  "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
+  "@
+   %D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1
+   #"
   [(set_attr "type" "delayed_compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC (match_operator:SI 1 "scc_comparison_operator"
+                                      [(match_operand 2 "cc_reg_operand" "")
+                                       (const_int 0)])
+                   (const_int 0)))
+   (set (match_operand:SI 3 "gpc_reg_operand" "")
+       (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (match_op_dup 1 [(match_dup 2) (const_int 0)]))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
  [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
-                                      [(match_operand 2 "cc_reg_operand" "y")
+                                      [(match_operand 2 "cc_reg_operand" "y,y")
                                        (const_int 0)])
-                   (match_operand:SI 3 "const_int_operand" "n"))
+                   (match_operand:SI 3 "const_int_operand" "n,n"))
         (const_int 0)))
-   (set (match_operand:SI 4 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
        (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
                   (match_dup 3)))]
-  ""
+  "! TARGET_POWERPC64"
   "*
 {
   int is_bit = ccr_bit (operands[1], 1);
   int put_bit = 31 - (INTVAL (operands[3]) & 31);
   int count;
 
+  /* Force split for non-cc0 compare.  */
+  if (which_alternative == 1)
+     return \"#\";
+
   if (is_bit >= put_bit)
     count = is_bit - put_bit;
   else
   return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
 }"
   [(set_attr "type" "delayed_compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
+                                      [(match_operand 2 "cc_reg_operand" "")
+                                       (const_int 0)])
+                   (match_operand:SI 3 "const_int_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 4 "gpc_reg_operand" "")
+       (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
+                  (match_dup 3)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
+                  (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 ;; If we are comparing the result of two comparisons, this can be done
 ;; using creqv or crxor.
    "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
    [(set_attr "length" "20")])
 
+(define_peephole
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (match_operator:DI 1 "scc_comparison_operator"
+                          [(match_operand 2 "cc_reg_operand" "y")
+                           (const_int 0)]))
+   (set (match_operand:DI 3 "gpc_reg_operand" "=r")
+       (match_operator:DI 4 "scc_comparison_operator"
+                          [(match_operand 5 "cc_reg_operand" "y")
+                           (const_int 0)]))]
+   "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
+   "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
+   [(set_attr "length" "20")])
+
 ;; There are some scc insns that can be done directly, without a compare.
 ;; These are faster because they don't involve the communications between
 ;; the FXU and branch units.   In fact, we will be replacing all of the
   [(set_attr "length" "12,8,12,12,12")])
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
        (compare:CC
-        (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
-               (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))
+        (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
+               (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
        (eq:SI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
+   (clobber (match_scratch:SI 3 "=r,&r,r,r,r,r,&r,r,r,r"))]
   "! TARGET_POWERPC64"
   "@
    xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
    {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
    {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
    {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
-   {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0"
+   {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
+   #
+   #
+   #
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12,8,12,12,12")])
+   (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
+               (match_operand:SI 2 "reg_or_cint_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (eq:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (eq:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
        (compare:CC
-        (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
-               (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I"))
+        (eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
+               (match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I,r,O,K,J,I"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
        (eq:DI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:DI 3 "=r,&r,r,r,r"))]
+   (clobber (match_scratch:DI 3 "=r,&r,r,r,r,r,&r,r,r,r"))]
   "TARGET_POWERPC64"
   "@
    xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0
    subfic %3,%1,0\;adde. %0,%3,%1
    xori %0,%1,%b2\;subfic %3,%0,0\;adde. %0,%3,%0
    xoris %0,%1,%u2\;subfic %3,%0,0\;adde. %0,%3,%0
-   subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0"
+   subfic %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0
+   #
+   #
+   #
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12,8,12,12,12")])
+   (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (eq:DI (match_operand:DI 1 "gpc_reg_operand" "")
+               (match_operand:DI 2 "reg_or_cint_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (eq:DI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (eq:DI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 ;; We have insns of the form shown by the first define_insn below.  If
 ;; there is something inside the comparison operation, we must split it.
   [(set_attr "length" "12,8,12,12,12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
        (compare:CC
         (plus:SI
-         (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
-                (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))
-         (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
+         (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
+                (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I"))
+         (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
    {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
    {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
    {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
-   {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
+   {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
+   #
+   #
+   #
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12,8,12,12,12")])
+   (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI
+         (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                (match_operand:SI 2 "reg_or_cint_operand" ""))
+         (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (eq:SI (match_dup 1)
+                (match_dup 2))
+         (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
        (compare:CC
         (plus:SI
-         (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
-                (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))
-         (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))
+         (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
+                (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I,r,O,K,L,I"))
+         (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
        (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
    {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3
    {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
    {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
-   {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
-  [(set_attr "type" "compare")
-   (set_attr "length" "12,8,12,12,12")])
-
+   {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
+   #
+   #
+   #
+   #
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI
+         (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                (match_operand:SI 2 "reg_or_cint_operand" ""))
+         (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
        (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
        (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
                     (const_int 31)))
    (clobber (match_scratch:SI 2 "=&r"))]
-  "! TARGET_POWER"
+  "! TARGET_POWER && ! TARGET_POWERPC64"
   "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
   [(set_attr "length" "8")])
 
   [(set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (plus:SI (lshiftrt:SI
-                  (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+                  (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")))
                   (const_int 31))
-                 (match_operand:SI 2 "gpc_reg_operand" "r"))
+                 (match_operand:SI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 3 "=&r"))]
+   (clobber (match_scratch:SI 3 "=&r,&r"))]
   "! TARGET_POWERPC64"
-  "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2"
+  "@
+   {ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (lshiftrt:SI
+                  (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))
+                  (const_int 31))
+                 (match_operand:SI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1)))
+                  (const_int 31))
+                 (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (plus:DI (lshiftrt:DI
-                  (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+                  (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")))
                   (const_int 63))
-                 (match_operand:DI 2 "gpc_reg_operand" "r"))
+                 (match_operand:DI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:DI 3 "=&r"))]
+   (clobber (match_scratch:DI 3 "=&r,&r"))]
   "TARGET_POWERPC64"
-  "addic %3,%1,-1\;addze. %3,%2"
+  "@
+   addic %3,%1,-1\;addze. %3,%2
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:DI (lshiftrt:DI
+                  (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))
+                  (const_int 63))
+                 (match_operand:DI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1)))
+                  (const_int 63))
+                 (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
         (plus:SI (lshiftrt:SI
-                  (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+                  (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")))
                   (const_int 31))
-                 (match_operand:SI 2 "gpc_reg_operand" "r"))
+                 (match_operand:SI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
                 (match_dup 2)))
-   (clobber (match_scratch:SI 3 "=&r"))]
+   (clobber (match_scratch:SI 3 "=&r,&r"))]
   "! TARGET_POWERPC64"
-  "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2"
+  "@
+   {ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (lshiftrt:SI
+                  (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))
+                  (const_int 31))
+                 (match_operand:SI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
+                (match_dup 2)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
+                (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
         (plus:DI (lshiftrt:DI
-                  (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+                  (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")))
                   (const_int 63))
-                 (match_operand:DI 2 "gpc_reg_operand" "r"))
+                 (match_operand:DI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
                 (match_dup 2)))
-   (clobber (match_scratch:DI 3 "=&r"))]
+   (clobber (match_scratch:DI 3 "=&r,&r"))]
   "TARGET_POWERPC64"
-  "addic %3,%1,-1\;addze. %0,%2"
+  "@
+   addic %3,%1,-1\;addze. %0,%2
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:DI (lshiftrt:DI
+                  (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))
+                  (const_int 63))
+                 (match_operand:DI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
+                (match_dup 2)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
+                (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-               (match_operand:SI 2 "reg_or_short_operand" "r,O"))
+        (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+               (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (le:SI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:SI 3 "=r,X"))]
+   (clobber (match_scratch:SI 3 "=r,X,r,X"))]
   "TARGET_POWER"
   "@
    doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
-   {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31"
-  [(set_attr "type" "compare,delayed_compare")
-   (set_attr "length" "12")])
+   {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31
+   #
+   #"
+  [(set_attr "type" "compare,delayed_compare,compare,delayed_compare")
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (le:SI (match_operand:SI 1 "gpc_reg_operand" "")
+               (match_operand:SI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (le:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:SI 3 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (le:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                        (match_operand:SI 2 "reg_or_short_operand" "r,O"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "TARGET_POWER"
   "@
    doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
-   {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3"
+   {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (le:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                        (match_operand:SI 2 "reg_or_short_operand" "r,O"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "TARGET_POWER"
   "@
    doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
-   {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3"
+   {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %0,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                (match_operand:DI 2 "reg_or_short_operand" "rI"))
+        (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                (match_operand:DI 2 "reg_or_short_operand" "rI,rI"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (leu:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0"
+  "@
+   subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (leu:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                (match_operand:DI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (leu:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (leu:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                (match_operand:SI 2 "reg_or_short_operand" "rI"))
+        (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (leu:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWERPC64"
-  "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
+  "@
+   {sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                (match_operand:SI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (leu:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (leu:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                (match_operand:DI 2 "reg_or_short_operand" "rI"))
+        (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                (match_operand:DI 2 "reg_or_short_operand" "rI,rI"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (leu:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0"
+  "@
+   subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                         (match_operand:SI 2 "reg_or_short_operand" "rI"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                         (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "! TARGET_POWERPC64"
-  "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3"
+  "@
+   {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (leu:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                         (match_operand:SI 2 "reg_or_short_operand" "rI"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                         (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "! TARGET_POWERPC64"
-  "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3"
+  "@
+   {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (and:SI (neg:SI
-                 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                         (match_operand:SI 2 "reg_or_short_operand" "rI")))
-                (match_operand:SI 3 "gpc_reg_operand" "r"))
+                 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                         (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
+                (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "! TARGET_POWERPC64"
-  "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
-  [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+  "@
+   {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (neg:SI
+                 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_short_operand" "")))
+                (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (and:SI (neg:SI (leu:SI (match_dup 1)
+                         (match_dup 2)))
+                (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
        (compare:CC
         (and:SI (neg:SI
-                 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                         (match_operand:SI 2 "reg_or_short_operand" "rI")))
-                (match_operand:SI 3 "gpc_reg_operand" "r"))
+                 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                         (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
+                (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "! TARGET_POWERPC64"
-  "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
+  "@
+   {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (neg:SI
+                 (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_short_operand" "")))
+                (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
    [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-               (match_operand:SI 2 "reg_or_short_operand" "rI"))
+        (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+               (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (lt:SI (match_dup 1) (match_dup 2)))]
   "TARGET_POWER"
-  "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
+  "@
+   doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31
+   #"
   [(set_attr "type" "delayed_compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (lt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+               (match_operand:SI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (lt:SI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (lt:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "reg_or_short_operand" "rI"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_POWER"
-  "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
+  "@
+   doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (lt:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "reg_or_short_operand" "rI"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_POWER"
-  "doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
+  "@
+   doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
+        (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (ltu:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
-   {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
+   {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                (match_operand:SI 2 "reg_or_neg_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ltu:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ltu:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
  [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
-   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
+   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (ltu:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
-   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
+   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
    [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+       (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+              (const_int 0)))]
+  "! TARGET_POWER && ! TARGET_POWERPC64"
+  "nand %0,%1,%1\;{sri|srwi} %0,%0,31"
+   [(set_attr "length" "8")])
+
+(define_insn ""
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (ge:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+              (const_int 0)))]
+  "TARGET_POWERPC64"
+  "nand %0,%1,%1\;srdi %0,%0,63"
+   [(set_attr "length" "8")])
+
+(define_insn ""
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-               (match_operand:SI 2 "reg_or_short_operand" "rI"))
+        (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+               (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (ge:SI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   "TARGET_POWER"
-  "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3"
+  "@
+   doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ge:SI (match_operand:SI 1 "gpc_reg_operand" "")
+               (match_operand:SI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ge:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_scratch:SI 3 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (ge:SI (match_dup 1) (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
+(define_insn ""
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+       (compare:CC
+        (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+               (const_int 0))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (ge:SI (match_dup 1) (const_int 0)))]
+  "! TARGET_POWER"
+  "@
+   nand %0,%1,%1\;{sri.|srwi.} %0,%0,31
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ge:SI (match_operand:SI 1 "gpc_reg_operand" "")
+               (const_int 0))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (ge:SI (match_dup 1) (const_int 0)))]
+  "! TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (ge:SI (match_dup 1) (const_int 0)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
+
+(define_insn ""
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+       (compare:CC
+        (ge:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+               (const_int 0))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+       (ge:DI (match_dup 1) (const_int 0)))]
+  "TARGET_POWERPC64"
+  "@
+   nand %0,%1,%1\;srdi. %0,%0,63
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (ge:DI (match_operand:DI 1 "gpc_reg_operand" "")
+               (const_int 0))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (ge:DI (match_dup 1) (const_int 0)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (ge:DI (match_dup 1) (const_int 0)))
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "reg_or_short_operand" "rI"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_POWER"
-  "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3"
+  "@
+   doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (ge:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "reg_or_short_operand" "rI"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_POWER"
-  "doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3"
+  "@
+   doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (and:SI (neg:SI
                  (lshiftrt:SI
-                  (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+                  (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
                   (const_int 31)))
-                (match_operand:SI 2 "gpc_reg_operand" "r"))
+                (match_operand:SI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 3 "=&r"))]
+   (clobber (match_scratch:SI 3 "=&r,&r"))]
   ""
-  "{srai|srawi} %3,%1,31\;andc. %3,%2,%3"
+  "@
+   {srai|srawi} %3,%1,31\;andc. %3,%2,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (neg:SI
+                 (lshiftrt:SI
+                  (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
+                  (const_int 31)))
+                (match_operand:SI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "reload_completed"
+  [(set (match_dup 3)
+       (and:SI (neg:SI (lshiftrt:SI
+                  (not:SI (match_dup 1))
+                  (const_int 31)))
+                (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
         (and:DI (neg:DI
                  (lshiftrt:DI
-                  (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+                  (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
                   (const_int 63)))
-                (match_operand:DI 2 "gpc_reg_operand" "r"))
+                (match_operand:DI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:DI 3 "=&r"))]
+   (clobber (match_scratch:DI 3 "=&r,&r"))]
   "TARGET_POWERPC64"
-  "sradi %3,%1,63\;andc. %3,%2,%3"
+  "@
+   sradi %3,%1,63\;andc. %3,%2,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:DI (neg:DI
+                 (lshiftrt:DI
+                  (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                  (const_int 63)))
+                (match_operand:DI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (and:DI (neg:DI (lshiftrt:DI
+                  (not:DI (match_dup 1))
+                  (const_int 63)))
+                (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+       (compare:CC
+        (and:SI (neg:SI
+                 (lshiftrt:SI
+                  (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+                  (const_int 31)))
+                (match_operand:SI 2 "gpc_reg_operand" "r,r"))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
+                                    (const_int 31)))
+               (match_dup 2)))
+   (clobber (match_scratch:SI 3 "=&r,&r"))]
+  ""
+  "@
+   {srai|srawi} %3,%1,31\;andc. %0,%2,%3
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
        (compare:CC
         (and:SI (neg:SI
                  (lshiftrt:SI
-                  (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+                  (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
                   (const_int 31)))
-                (match_operand:SI 2 "gpc_reg_operand" "r"))
+                (match_operand:SI 2 "gpc_reg_operand" ""))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
        (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
                                     (const_int 31)))
                (match_dup 2)))
-   (clobber (match_scratch:SI 3 "=&r"))]
-  ""
-  "{srai|srawi} %3,%1,31\;andc. %0,%2,%3"
-  [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (clobber (match_scratch:SI 3 ""))]
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+       (and:SI (neg:SI (lshiftrt:SI (not:SI (match_dup 1))
+                                    (const_int 31)))
+               (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
         (and:DI (neg:DI
                  (lshiftrt:DI
-                  (not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
+                  (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
                   (const_int 63)))
-                (match_operand:DI 2 "gpc_reg_operand" "r"))
+                (match_operand:DI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1))
                                     (const_int 63)))
                (match_dup 2)))
-   (clobber (match_scratch:SI 3 "=&r"))]
+   (clobber (match_scratch:SI 3 "=&r,&r"))]
   "TARGET_POWERPC64"
-  "sradi %3,%1,63\;andc. %0,%2,%3"
+  "@
+   sradi %3,%1,63\;andc. %0,%2,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,12")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:DI (neg:DI
+                 (lshiftrt:DI
+                  (not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
+                  (const_int 63)))
+                (match_operand:DI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1))
+                                    (const_int 63)))
+               (match_dup 2)))
+   (clobber (match_scratch:SI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1))
+                                    (const_int 63)))
+               (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
+        (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (geu:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
-   {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0"
+   {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                (match_operand:SI 2 "reg_or_neg_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (geu:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (geu:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                (match_operand:DI 2 "reg_or_neg_short_operand" "r,P"))
+        (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                (match_operand:DI 2 "reg_or_neg_short_operand" "r,P,r,P"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (geu:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
   "@
    subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
-   addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0"
+   addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (geu:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                (match_operand:DI 2 "reg_or_neg_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (geu:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (geu:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
   [(set_attr "length" "8")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
-   {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3"
+   {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,8,12,12")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (geu:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3
-   {ai|addic} %4,%1,%n2\;{aze.|addze.} %0,%3"
+   {ai|addic} %4,%1,%n2\;{aze.|addze.} %0,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8")])
+   (set_attr "length" "8,8,12,12")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
         (and:SI (neg:SI
-                 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
-                (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+                 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
+                (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
-   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4"
+   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (neg:SI
+                 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "")))
+                (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (and:SI (neg:SI (geu:SI (match_dup 1)
+                         (match_dup 2)))
+                (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
         (and:SI (neg:SI
-                 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
-                (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+                 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
+                (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
-   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4"
+   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,12,16,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (and:SI (neg:SI
+                 (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_neg_short_operand" "")))
+                (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                (const_int 0))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (gt:SI (match_dup 1) (const_int 0)))]
   "! TARGET_POWERPC64"
-  "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31"
+  "@
+   {sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31
+   #"
   [(set_attr "type" "delayed_compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+               (const_int 0))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (gt:SI (match_dup 1) (const_int 0)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (gt:SI (match_dup 1) (const_int 0)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+        (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
                (const_int 0))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (gt:DI (match_dup 1) (const_int 0)))]
   "TARGET_POWERPC64"
-  "subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63"
+  "@
+   subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63
+   #"
   [(set_attr "type" "delayed_compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+               (const_int 0))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (gt:DI (match_dup 1) (const_int 0)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (gt:DI (match_dup 1) (const_int 0)))
+   (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-               (match_operand:SI 2 "reg_or_short_operand" "r"))
+        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+               (match_operand:SI 2 "reg_or_short_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (gt:SI (match_dup 1) (match_dup 2)))]
   "TARGET_POWER"
-  "doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31"
+  "@
+   doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31
+   #"
   [(set_attr "type" "delayed_compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+               (match_operand:SI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (gt:SI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 0)
+       (gt:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
                         (const_int 0))
-                 (match_operand:SI 2 "gpc_reg_operand" "r"))
+                 (match_operand:SI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 3 "=&r"))]
+   (clobber (match_scratch:SI 3 "=&r,&r"))]
   "! TARGET_POWERPC64"
-  "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2"
+  "@
+   {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (const_int 0))
+                 (match_operand:SI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (plus:SI (gt:SI (match_dup 1) (const_int 0))
+                 (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
                         (const_int 0))
-                 (match_operand:DI 2 "gpc_reg_operand" "r"))
+                 (match_operand:DI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:DI 3 "=&r"))]
+   (clobber (match_scratch:DI 3 "=&r,&r"))]
   "TARGET_POWERPC64"
-  "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2"
+  "@
+   addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                        (const_int 0))
+                 (match_operand:DI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 3)
+       (plus:DI (gt:DI (match_dup 1) (const_int 0))
+                 (match_dup 2)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 3)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
+       (compare:CC
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (const_int 0))
+                 (match_operand:SI 2 "gpc_reg_operand" "r,r"))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
+   (clobber (match_scratch:SI 3 "=&r,&r"))]
+  "! TARGET_POWERPC64"
+  "@
+   {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2
+   #"
+  [(set_attr "type" "compare")
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
        (compare:CC
-        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
                         (const_int 0))
-                 (match_operand:SI 2 "gpc_reg_operand" "r"))
+                 (match_operand:SI 2 "gpc_reg_operand" ""))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
        (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
-   (clobber (match_scratch:SI 3 "=&r"))]
-  "! TARGET_POWERPC64"
-  "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2"
-  [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (clobber (match_scratch:SI 3 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
                         (const_int 0))
-                 (match_operand:DI 2 "gpc_reg_operand" "r"))
+                 (match_operand:DI 2 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
-   (clobber (match_scratch:DI 3 "=&r"))]
+   (clobber (match_scratch:DI 3 "=&r,&r"))]
   "TARGET_POWERPC64"
-  "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %0,%2"
+  "@
+   addc %3,%1,%1\;subfe %3,%1,%3\;addze. %0,%2
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                        (const_int 0))
+                 (match_operand:DI 2 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
+   (clobber (match_scratch:DI 3 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
+   (clobber (match_dup 3))])
+   (set (match_dup 4)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "reg_or_short_operand" "r"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "r,r"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_POWER"
-  "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3"
+  "@
+   doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (gt:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                        (match_operand:SI 2 "reg_or_short_operand" "r"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r"))
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                        (match_operand:SI 2 "reg_or_short_operand" "r,r"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r"))]
   "TARGET_POWER"
-  "doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3"
+  "@
+   doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %0,%3
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                        (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "TARGET_POWER && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
   [(set_attr "length" "12")])
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                (match_operand:SI 2 "reg_or_short_operand" "rI"))
+        (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
+                (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (gtu:SI (match_dup 1) (match_dup 2)))]
   "! TARGET_POWERPC64"
-  "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0"
+  "@
+   {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                (match_operand:SI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (gtu:SI (match_dup 1) (match_dup 2)))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (gtu:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
        (compare:CC
-        (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-                (match_operand:DI 2 "reg_or_short_operand" "rI"))
+        (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
+                (match_operand:DI 2 "reg_or_short_operand" "rI,rI"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
        (gtu:DI (match_dup 1) (match_dup 2)))]
   "TARGET_POWERPC64"
-  "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0"
+  "@
+   subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "12")])
+   (set_attr "length" "12,16")])
+
+(define_split
+  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                (match_operand:DI 2 "reg_or_short_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (gtu:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 0)
+       (gtu:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
   [(set_attr "length" "8,12")])
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_short_operand" "I,r"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3
-   {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3"
+   {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,12")])
+   (set_attr "length" "8,12,12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (plus:SI (gtu:SI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:DI 2 "reg_or_short_operand" "I,r"))
-                 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
+        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:DI 2 "reg_or_short_operand" "I,r,I,r"))
+                 (match_operand:DI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (clobber (match_scratch:DI 4 "=&r,&r"))]
+   (clobber (match_scratch:DI 4 "=&r,&r,&r,&r"))]
   "TARGET_POWERPC64"
   "@
    addic %4,%1,%k2\;addze. %4,%3
-   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3"
+   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,12")])
+   (set_attr "length" "8,12,12,16")])
+
+(define_split
+  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                         (match_operand:DI 2 "reg_or_short_operand" ""))
+                 (match_operand:DI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (clobber (match_scratch:DI 4 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(set (match_dup 4)
+       (plus:DI (gtu:DI (match_dup 1) (match_dup 2))
+                 (match_dup 3)))
+   (set (match_dup 0)
+       (compare:CC (match_dup 4)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:SI 2 "reg_or_short_operand" "I,r"))
-                 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
+        (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:SI 2 "reg_or_short_operand" "I,r,I,r"))
+                 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
        (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:SI 4 "=&r,&r"))]
+   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
   "! TARGET_POWERPC64"
   "@
    {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3
-   {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3"
+   {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,12")])
+   (set_attr "length" "8,12,12,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "")
+                         (match_operand:SI 2 "reg_or_short_operand" ""))
+                 (match_operand:SI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:SI 4 ""))]
+  "! TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
-  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x")
+  [(set (match_operand:CC 5 "cc_reg_operand" "=x,x,?y,?y")
        (compare:CC
-        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
-                         (match_operand:DI 2 "reg_or_short_operand" "I,r"))
-                 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
+        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r")
+                         (match_operand:DI 2 "reg_or_short_operand" "I,r,I,r"))
+                 (match_operand:DI 3 "gpc_reg_operand" "r,r,r,r"))
         (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
        (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
-   (clobber (match_scratch:DI 4 "=&r,&r"))]
+   (clobber (match_scratch:DI 4 "=&r,&r,&r,&r"))]
   "TARGET_POWERPC64"
   "@
    addic %4,%1,%k2\;addze. %0,%3
-   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %0,%4,%3"
+   subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %0,%4,%3
+   #
+   #"
   [(set_attr "type" "compare")
-   (set_attr "length" "8,12")])
+   (set_attr "length" "8,12,12,16")])
+
+(define_split
+  [(set (match_operand:CC 5 "cc_reg_not_cr0_operand" "")
+       (compare:CC
+        (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "")
+                         (match_operand:DI 2 "reg_or_short_operand" ""))
+                 (match_operand:DI 3 "gpc_reg_operand" ""))
+        (const_int 0)))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_scratch:DI 4 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 0)
+       (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
+   (clobber (match_dup 4))])
+   (set (match_dup 5)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+  "")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 }")
 
 (define_expand "tablejumpdi"
-  [(set (match_dup 3)
-       (plus:DI (match_operand:DI 0 "" "")
+  [(set (match_dup 4) 
+        (sign_extend:DI (match_operand:SI 0 "lwa_operand" "rm")))
+   (set (match_dup 3)
+       (plus:DI (match_dup 4)
                 (match_dup 2)))
    (parallel [(set (pc) (match_dup 3))
              (use (label_ref (match_operand 1 "" "")))])]
   "TARGET_64BIT"
   "
-{ operands[0] = force_reg (DImode, operands[0]);
-  operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
+{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
   operands[3] = gen_reg_rtx (DImode);
+  operands[4] = gen_reg_rtx (DImode);
 }")
 
 (define_insn ""
                                       (const_int 1)])
                      (match_operand 5 "" "")
                      (match_operand 6 "" "")))
-   (set (match_operand:SI 0 "general_operand" "")
+   (set (match_operand:SI 0 "nonimmediate_operand" "")
        (plus:SI (match_dup 1) (const_int -1)))
    (clobber (match_scratch:CC 3 ""))
    (clobber (match_scratch:SI 4 ""))]
                                       (const_int 1)])
                      (match_operand 5 "" "")
                      (match_operand 6 "" "")))
-   (set (match_operand:DI 0 "general_operand" "")
+   (set (match_operand:DI 0 "nonimmediate_operand" "")
        (plus:DI (match_dup 1) (const_int -1)))
    (clobber (match_scratch:CC 3 ""))
    (clobber (match_scratch:DI 4 ""))]
            (const_int 0))]
   "TARGET_POWERPC64"
   "td%V0%I2 %1,%2")
+\f
+;; Insns related to generating the function prologue and epilogue.
+
+(define_expand "prologue"
+  [(use (const_int 0))]
+  "TARGET_SCHED_PROLOG"
+  "
+{
+      rs6000_emit_prologue ();
+      DONE;
+}")
+
+(define_insn "movesi_from_cr"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+        (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) 
+                   (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
+  ""
+  "mfcr %0")
+
+(define_insn "*stmw"
+ [(match_parallel 0 "stmw_operation"
+                 [(set (match_operand:SI 1 "memory_operand" "=m")
+                               (match_operand:SI 2 "gpc_reg_operand" "r"))])]
+ "TARGET_MULTIPLE"
+ "{stm|stmw} %2,%1")
+(define_insn "*save_fpregs_si"
+ [(match_parallel 0 "any_operand"
+                  [(clobber (match_operand:SI 1 "register_operand" "=l"))
+                  (use (match_operand:SI 2 "call_operand" "s"))
+                  (set (match_operand:DF 3 "memory_operand" "=m")
+                       (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+ "TARGET_32BIT"
+ "bl %z2")
+
+(define_insn "*save_fpregs_di"
+ [(match_parallel 0 "any_operand"
+                  [(clobber (match_operand:DI 1 "register_operand" "=l"))
+                  (use (match_operand:DI 2 "call_operand" "s"))
+                  (set (match_operand:DF 3 "memory_operand" "=m")
+                       (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+ "TARGET_64BIT"
+ "bl %z2")
+
+; These are to explain that changes to the stack pointer should
+; not be moved over stores to stack memory.
+(define_insn "stack_tie"
+  [(set (match_operand:BLK 0 "memory_operand" "+m")
+        (unspec:BLK [(match_dup 0)] 5))]
+  ""
+  ""
+  [(set_attr "length" "0")])
+
+
+(define_expand "epilogue"
+  [(use (const_int 0))]
+  "TARGET_SCHED_PROLOG"
+  "
+{
+      rs6000_emit_epilogue (FALSE);
+      DONE;
+}")
+
+; On some processors, doing the mtcrf one CC register at a time is
+; faster (like on the 604e).  On others, doing them all at once is
+; faster; for instance, on the 601 and 750.
+
+(define_expand "movsi_to_cr_one"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=y")
+       (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+                  (match_dup 2)] 20))]
+ ""
+ "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
+
+(define_insn "*movsi_to_cr"
+ [(match_parallel 0 "mtcrf_operation"
+                  [(use (match_operand 1 "immediate_operand" "n"))
+                  (set (match_operand:CC 2 "cc_reg_operand" "=y")
+                               (unspec:CC [(match_operand:SI 3 "gpc_reg_operand" "r")
+                                   (match_operand 4 "immediate_operand" "n")]
+                        20))])]
+ ""
+ "mtcrf %1,%3")
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=y")
+       (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+                  (match_operand 2 "immediate_operand" "n")] 20))]
+ "GET_CODE (operands[0]) == REG 
+  && CR_REGNO_P (REGNO (operands[0]))
+  && GET_CODE (operands[2]) == CONST_INT
+  && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
+ "mtcrf %R0,%1")
+
+; The load-multiple instructions have similar properties.
+; Note that "load_multiple" is a name known to the machine-independent
+; code that actually corresponds to the powerpc load-string.
+
+(define_insn "*lmw"
+ [(match_parallel 0 "lmw_operation"
+                 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
+                               (match_operand:SI 2 "memory_operand" "m"))])]
+ "TARGET_MULTIPLE"
+ "{lm|lmw} %1,%2")
+(define_insn "*return_internal_si"
+  [(use (match_operand:SI 0 "register_operand" "l,c"))
+   (return)]
+  "TARGET_32BIT"
+  "@
+   {br|blr}
+   bctr"
+  [(set_attr "type" "jmpreg")])
+
+(define_insn "*return_internal_di"
+  [(use (match_operand:DI 0 "register_operand" "l,c"))
+   (return)]
+  "TARGET_64BIT"
+  "@
+   {br|blr}
+   bctr"
+  [(set_attr "type" "jmpreg")])
+
+; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
+; stuff was in GCC.  Oh, and "any_operand" is a bit flexible...
+
+(define_insn "*return_and_restore_fpregs_si"
+ [(match_parallel 0 "any_operand"
+                  [(use (match_operand:SI 1 "register_operand" "l"))
+                  (return)
+                  (use (match_operand:SI 2 "call_operand" "s"))
+                  (set (match_operand:DF 3 "gpc_reg_operand" "=f")
+                       (match_operand:DF 4 "memory_operand" "m"))])]
+ "TARGET_32BIT"
+ "b %z2")
+
+(define_insn "*return_and_restore_fpregs_di"
+ [(match_parallel 0 "any_operand"
+                  [(use (match_operand:DI 1 "register_operand" "l"))
+                  (return)
+                  (use (match_operand:DI 2 "call_operand" "s"))
+                  (set (match_operand:DF 3 "gpc_reg_operand" "=f")
+                       (match_operand:DF 4 "memory_operand" "m"))])]
+ "TARGET_64BIT"
+ "b %z2")
+
+; This is used in compiling the routines __throw and __rethrow.
+; It's a little different to the usual definition...
+
+(define_expand "eh_epilogue"
+  [(use (match_operand 0 "general_operand" "r"))
+   (use (match_operand 1 "general_operand" "r"))
+   (use (match_operand 2 "general_operand" "c"))]
+  ""
+  "
+{
+  rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+  rtx insn;
+
+  /* This is required for binary compatibility.  If it's wrong,
+     it probably means that eh_regs() in except.c is broken.  */
+  if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 3)
+    abort();
+
+  /* These can be anything that doesn't interfere with the epilogue.  */
+  if (GET_CODE (operands[1]) != REG || REGNO (operands[1]) != 4)
+    {
+      rtx r = gen_rtx_REG (Pmode, 4);
+      emit_move_insn (r, operands[1]);
+      operands[1] = r;
+    }
+
+  if (GET_CODE (operands[2]) != REG 
+       || REGNO (operands[2]) != COUNT_REGISTER_REGNUM)
+    {
+      rtx r = gen_rtx_REG (Pmode, COUNT_REGISTER_REGNUM);
+      emit_move_insn (r, operands[2]);
+      operands[2] = r;
+    }
+
+#if TARGET_AIX
+    rs6000_emit_eh_toc_restore (operands[1]);
+#endif
+
+  emit_insn (gen_eh_reg_restore ());
+
+  if (Pmode == SImode)
+    emit_insn (gen_addsi3 (stack_reg, stack_reg, operands[1]));
+  else
+    emit_insn (gen_adddi3 (stack_reg, stack_reg, operands[1]));
+  
+  if (Pmode == SImode)
+    insn = emit_jump_insn (gen_return_eh_si (operands[2]));
+  else
+    insn = emit_jump_insn (gen_return_eh_di (operands[2]));
+  emit_barrier_after (insn);
+
+  DONE;
+}")
+
+; We can't expand this before we know which registers are restored,
+; but we do want to expand it before flow2 because that way flow2 can
+; remove the redundant loads of the link register.
+(define_expand "eh_reg_restore"
+  [(unspec_volatile [(const_int 0)] 9)]
+  ""
+  "")
+
+(define_split
+  [(unspec_volatile [(const_int 0)] 9)]
+  "reload_completed && TARGET_SCHED_PROLOG"
+  [(unspec_volatile [(const_int 0)] 9)]
+  "
+{
+  rs6000_emit_epilogue (TRUE);
+  DONE;
+}")
+
+(define_insn ""
+  [(unspec_volatile [(const_int 0)] 9)]
+  ""
+  "*
+{
+  if (TARGET_SCHED_PROLOG)
+    return \"#\";
+
+  /* This is slightly ugly, but at least we don't have multiple
+     copies of the epilogue-emitting code.  */
+  start_sequence ();
+
+  /* A NOTE_INSN_DELETED is supposed to be at the start
+     and end of the \"toplevel\" insn chain.  */
+  emit_note (0, NOTE_INSN_DELETED);
+  rs6000_emit_epilogue (TRUE);
+  emit_note (0, NOTE_INSN_DELETED);
+
+  if (TARGET_DEBUG_STACK)
+    debug_rtx_list (get_insns(), 100);
+  final (get_insns(), asm_out_file, FALSE, FALSE);
+  end_sequence ();
+  return \"\";
+}")
+
+
+(define_insn "return_eh_si"
+  [(use (match_operand:SI 0 "register_operand" "l,c"))
+   (return)
+   (use (reg:SI 2))
+   (use (reg:SI 3))]
+  "TARGET_32BIT"
+  "@
+   {br|blr}
+   bctr"
+  [(set_attr "type" "jmpreg")])
+
+(define_insn "return_eh_di"
+  [(use (match_operand:DI 0 "register_operand" "l,c"))
+   (return)
+   (use (reg:DI 2))
+   (use (reg:DI 3))]
+  "TARGET_64BIT"
+  "@
+   {br|blr}
+   bctr"
+  [(set_attr "type" "jmpreg")])
index 91e5b42..76df9b0 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 running AIX version 3.1.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
    Contributed by David Reese (Dave.Reese@East.Sun.COM)
 
 This file is part of GNU CC.
@@ -65,9 +65,6 @@ Boston, MA 02111-1307, USA.  */
 #undef CPP_ENDIAN_LITTLE_SPEC
 #define        CPP_ENDIAN_LITTLE_SPEC CPP_ENDIAN_SOLARIS_SPEC
 
-/* Don't turn -B into -L if the argument specifies a relative file name.  */
-#undef RELATIVE_PREFIX_NOT_LINKDIR
-
 #define        DEFAULT_PCC_STRUCT_RETURN 0
 
 #undef TARGET_VERSION
index 1392204..644438c 100644 (file)
@@ -1,5 +1,5 @@
 /* Target definitions for GNU compiler for PowerPC running System V.4
-   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GNU CC.
@@ -19,109 +19,126 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* Small data support types */
+#include "rs6000/rs6000.h"
+
+/* Use the regular svr4 definitions.  */
+
+#include "svr4.h"
+
+/* Yes!  We are ELF.  */
+#define        TARGET_OBJECT_FORMAT OBJECT_ELF
+
+/* Default ABI to compile code for.  */
+#define DEFAULT_ABI rs6000_current_abi
+
+/* Default ABI to use.  */
+#define RS6000_ABI_NAME "sysv"
+
+/* Override rs6000.h definition.  */
+#undef ASM_DEFAULT_SPEC
+#define        ASM_DEFAULT_SPEC "-mppc"
+
+/* Override rs6000.h definition.  */
+#undef CPP_DEFAULT_SPEC
+#define        CPP_DEFAULT_SPEC "-D_ARCH_PPC"
+
+/* Small data support types.  */
 enum rs6000_sdata_type {
-  SDATA_NONE,                  /* no small data support */
-  SDATA_DATA,                  /* just put data in .sbss/.sdata, don't use relocs */
-  SDATA_SYSV,                  /* Use r13 to point to .sdata/.sbss */
-  SDATA_EABI                   /* Use r13 like above, r2 points to .sdata2/.sbss2 */
+  SDATA_NONE,                  /* No small data support.  */
+  SDATA_DATA,                  /* Just put data in .sbss/.sdata, don't use relocs.  */
+  SDATA_SYSV,                  /* Use r13 to point to .sdata/.sbss */
+  SDATA_EABI                   /* Use r13 like above, r2 points to .sdata2/.sbss2 */
 };
 
 extern enum rs6000_sdata_type rs6000_sdata;
 
-/* V.4/eabi switches */
-#define        MASK_NO_BITFIELD_TYPE   0x40000000      /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
+/* V.4/eabi switches */
+#define        MASK_NO_BITFIELD_TYPE   0x40000000      /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
 #define        MASK_STRICT_ALIGN       0x20000000      /* Set STRICT_ALIGNMENT to 1.  */
-#define MASK_RELOCATABLE       0x10000000      /* GOT pointers are PC relative */
-#define        MASK_EABI               0x08000000      /* Adhere to eabi, not System V spec */
-#define MASK_LITTLE_ENDIAN     0x04000000      /* target is little endian */
-#define MASK_REGNAMES          0x02000000      /* use alternate register names.  */
-#define MASK_PROTOTYPE         0x01000000      /* Only prototyped fcns pass variable args */
+#define        MASK_RELOCATABLE        0x10000000      /* GOT pointers are PC relative.  */
+#define        MASK_EABI               0x08000000      /* Adhere to eabi, not System V spec */
+#define        MASK_LITTLE_ENDIAN      0x04000000      /* Target is little endian.  */
+#define        MASK_REGNAMES           0x02000000      /* Use alternate register names.  */
+#define        MASK_PROTOTYPE          0x01000000      /* Only prototyped fcns pass variable args.  */
 
 #define        TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
-#define TARGET_STRICT_ALIGN    (target_flags & MASK_STRICT_ALIGN)
-#define TARGET_RELOCATABLE     (target_flags & MASK_RELOCATABLE)
-#define TARGET_EABI            (target_flags & MASK_EABI)
-#define TARGET_LITTLE_ENDIAN   (target_flags & MASK_LITTLE_ENDIAN)
-#define TARGET_REGNAMES                (target_flags & MASK_REGNAMES)
+#define        TARGET_STRICT_ALIGN     (target_flags & MASK_STRICT_ALIGN)
+#define        TARGET_RELOCATABLE      (target_flags & MASK_RELOCATABLE)
+#define        TARGET_EABI             (target_flags & MASK_EABI)
+#define        TARGET_LITTLE_ENDIAN    (target_flags & MASK_LITTLE_ENDIAN)
+#define        TARGET_REGNAMES         (target_flags & MASK_REGNAMES)
 #define        TARGET_PROTOTYPE        (target_flags & MASK_PROTOTYPE)
 #define        TARGET_TOC              ((target_flags & MASK_64BIT)            \
                                 || ((target_flags & (MASK_RELOCATABLE  \
                                                      | MASK_MINIMAL_TOC)) \
                                     && flag_pic > 1)                   \
-                                || DEFAULT_ABI == ABI_AIX              \
-                                || DEFAULT_ABI == ABI_NT)
+                                || DEFAULT_ABI == ABI_AIX)
 
 #define        TARGET_BITFIELD_TYPE    (! TARGET_NO_BITFIELD_TYPE)
-#define TARGET_BIG_ENDIAN      (! TARGET_LITTLE_ENDIAN)
+#define        TARGET_BIG_ENDIAN       (! TARGET_LITTLE_ENDIAN)
 #define        TARGET_NO_PROTOTYPE     (! TARGET_PROTOTYPE)
 #define        TARGET_NO_TOC           (! TARGET_TOC)
-#define TARGET_NO_EABI         (! TARGET_EABI)
-
-/* Pseudo target to indicate whether the object format is ELF
-   (to get around not having conditional compilation in the md file)  */
-#define        TARGET_ELF              1
-
-/* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be just
-   the same as -mminimal-toc.  */
-#undef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES                                             \
-  { "bit-align",       -MASK_NO_BITFIELD_TYPE },                       \
-  { "no-bit-align",     MASK_NO_BITFIELD_TYPE },                       \
-  { "strict-align",     MASK_STRICT_ALIGN },                           \
-  { "no-strict-align", -MASK_STRICT_ALIGN },                           \
-  { "relocatable",      MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
-  { "no-relocatable",  -MASK_RELOCATABLE },                            \
-  { "relocatable-lib",  MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
-  { "no-relocatable-lib", -MASK_RELOCATABLE },                         \
-  { "little-endian",    MASK_LITTLE_ENDIAN },                          \
-  { "little",           MASK_LITTLE_ENDIAN },                          \
-  { "big-endian",      -MASK_LITTLE_ENDIAN },                          \
-  { "big",             -MASK_LITTLE_ENDIAN },                          \
-  { "no-toc",           0 },                                           \
-  { "toc",              MASK_MINIMAL_TOC },                            \
-  { "full-toc",                 MASK_MINIMAL_TOC },                            \
-  { "prototype",        MASK_PROTOTYPE },                              \
-  { "no-prototype",    -MASK_PROTOTYPE },                              \
-  { "no-traceback",     0 },                                           \
-  { "eabi",             MASK_EABI },                                   \
-  { "no-eabi",         -MASK_EABI },                                   \
-  { "regnames",                  MASK_REGNAMES },                              \
-  { "no-regnames",      -MASK_REGNAMES },                              \
-  { "sdata",            0 },                                           \
-  { "no-sdata",                 0 },                                           \
-  { "sim",              0 },                                           \
-  { "ads",              0 },                                           \
-  { "yellowknife",      0 },                                           \
-  { "mvme",             0 },                                           \
-  { "emb",              0 },                                           \
-  { "solaris-cclib",    0 },                                           \
-  { "shlib",            0 },                                           \
-  EXTRA_SUBTARGET_SWITCHES                                              \
-  { "newlib",           0 },
-
-/* This is meant to be redefined in the host dependent files */
-#define EXTRA_SUBTARGET_SWITCHES
-
-/* Default ABI to use */
-#define RS6000_ABI_NAME "sysv"
+#define        TARGET_NO_EABI          (! TARGET_EABI)
 
 /* Strings provided by SUBTARGET_OPTIONS */
 extern const char *rs6000_abi_name;
 extern const char *rs6000_sdata_name;
 
-#define SUBTARGET_OPTIONS                                              \
-  { "call-",  &rs6000_abi_name},                                       \
-  { "sdata=", &rs6000_sdata_name}
+/* Override rs6000.h definition.  */
+#undef SUBTARGET_OPTIONS
+#define        SUBTARGET_OPTIONS                                               \
+  { "call-",  &rs6000_abi_name, "Select ABI calling convention." },                    \
+  { "sdata=", &rs6000_sdata_name, "Select method for sdata handling." }
 
 /* Max # of bytes for variables to automatically be put into the .sdata
    or .sdata2 sections.  */
-extern int g_switch_value;             /* value of the -G xx switch */
-extern int g_switch_set;               /* whether -G xx was passed.  */
+extern int g_switch_value;             /* Value of the -G xx switch.  */
+extern int g_switch_set;               /* Whether -G xx was passed.  */
 
-#ifndef SDATA_DEFAULT_SIZE
 #define SDATA_DEFAULT_SIZE 8
-#endif
+
+/* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be just
+   the same as -mminimal-toc.  */
+/* Override rs6000.h definition.  */
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES                                             \
+  { "bit-align",       -MASK_NO_BITFIELD_TYPE, "Align to the base type of the bitfield." },\
+  { "no-bit-align",     MASK_NO_BITFIELD_TYPE, "Don't align to the base type of the bitfield." },\
+  { "strict-align",     MASK_STRICT_ALIGN, "Don't assume that unaligned accesses are handled by the system" },\
+  { "no-strict-align", -MASK_STRICT_ALIGN, "Assume that unaligned accesses are handled by the system" },\
+  { "relocatable",      MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC, "Produce code relocatable at runtime." },\
+  { "no-relocatable",  -MASK_RELOCATABLE, "Don't produce code relocatable at runtime." },\
+  { "relocatable-lib",  MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC, "Produce code relocatable at runtime." },\
+  { "no-relocatable-lib", -MASK_RELOCATABLE, "Don't produce code relocatable at runtime." },\
+  { "little-endian",    MASK_LITTLE_ENDIAN, "Produce little endian code." },   \
+  { "little",           MASK_LITTLE_ENDIAN, "Produce little endian code." },   \
+  { "big-endian",      -MASK_LITTLE_ENDIAN, "Produce big endian code." },      \
+  { "big",             -MASK_LITTLE_ENDIAN, "Produce big endian code." },      \
+  { "no-toc",           0, "no description yet" },                             \
+  { "toc",              MASK_MINIMAL_TOC, "no description yet" },              \
+  { "full-toc",                 MASK_MINIMAL_TOC, "no description yet" },              \
+  { "prototype",        MASK_PROTOTYPE, "no description yet" },                \
+  { "no-prototype",    -MASK_PROTOTYPE, "no description yet" },                \
+  { "no-traceback",     0, "no description yet" },                             \
+  { "eabi",             MASK_EABI, "Use EABI." },                              \
+  { "no-eabi",         -MASK_EABI, "Don't use EABI." },                        \
+  { "regnames",                  MASK_REGNAMES, "Use alternate register names." },     \
+  { "no-regnames",      -MASK_REGNAMES, "Don't use alternate register names." },\
+  { "sdata",            0, "no description yet" },                             \
+  { "no-sdata",                 0, "no description yet" },                             \
+  { "sim",              0, "Link with libsim.a, libc.a and sim-crt0.o." },     \
+  { "ads",              0, "Link with libads.a, libc.a and crt0.o." },         \
+  { "yellowknife",      0, "Link with libyk.a, libc.a and crt0.o." },          \
+  { "mvme",             0, "Link with libmvme.a, libc.a and crt0.o." },        \
+  { "emb",              0, "Set the PPC_EMB bit in the ELF flags header" },    \
+  { "vxworks",          0, "no description yet" },                             \
+  { "solaris-cclib",    0, "no description yet" },                             \
+  { "shlib",            0, "no description yet" },                             \
+  EXTRA_SUBTARGET_SWITCHES                                                     \
+  { "newlib",           0, "no description yet" },
+
+/* This is meant to be redefined in the host dependent files.  */
+#define EXTRA_SUBTARGET_SWITCHES
 
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
@@ -157,8 +174,6 @@ do {                                                                        \
     }                                                                  \
   else if (!strcmp (rs6000_abi_name, "aixdesc"))                       \
     rs6000_current_abi = ABI_AIX;                                      \
-  else if (!strcmp (rs6000_abi_name, "nt"))                            \
-    rs6000_current_abi = ABI_NT;                                       \
   else if (!strcmp (rs6000_abi_name, "linux"))                         \
     rs6000_current_abi = ABI_V4;                                       \
   else if (!strcmp (rs6000_abi_name, "solaris"))                       \
@@ -226,16 +241,14 @@ do {                                                                      \
       error ("-mrelocatable and -mno-minimal-toc are incompatible.");  \
     }                                                                  \
                                                                        \
-  if (TARGET_RELOCATABLE &&                                            \
-      (rs6000_current_abi == ABI_AIX || rs6000_current_abi == ABI_NT)) \
+  if (TARGET_RELOCATABLE && rs6000_current_abi == ABI_AIX)             \
     {                                                                  \
       target_flags &= ~MASK_RELOCATABLE;                               \
       error ("-mrelocatable and -mcall-%s are incompatible.",          \
             rs6000_abi_name);                                          \
     }                                                                  \
                                                                        \
-  if (flag_pic > 1 &&                                                  \
-      (rs6000_current_abi == ABI_AIX || rs6000_current_abi == ABI_NT)) \
+  if (flag_pic > 1 && rs6000_current_abi == ABI_AIX)                   \
     {                                                                  \
       flag_pic = 0;                                                    \
       error ("-fPIC and -mcall-%s are incompatible.",                  \
@@ -248,13 +261,7 @@ do {                                                                       \
       error ("-mcall-aixdesc must be big endian");                     \
     }                                                                  \
                                                                        \
-  if (rs6000_current_abi == ABI_NT && TARGET_BIG_ENDIAN)               \
-    {                                                                  \
-      target_flags |= MASK_LITTLE_ENDIAN;                              \
-      error ("-mcall-nt must be little endian");                       \
-    }                                                                  \
-                                                                       \
-  /* Treat -fPIC the same as -mrelocatable */                          \
+  /* Treat -fPIC the same as -mrelocatable.  */                                \
   if (flag_pic > 1)                                                    \
     target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \
                                                                        \
@@ -263,42 +270,30 @@ do {                                                                      \
                                                                        \
 } while (0)
 
-/* Default ABI to compile code for */
-#define DEFAULT_ABI rs6000_current_abi
-
-#define CPP_DEFAULT_SPEC "-D_ARCH_PPC"
-
-#define ASM_DEFAULT_SPEC "-mppc"
-
-#include "rs6000/rs6000.h"
 
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS)
+/* Override rs6000.h definition.  */
+#undef TARGET_DEFAULT
+#define        TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS)
 
-#undef PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_PPC750
+/* Override rs6000.h definition.  */
+#undef PROCESSOR_DEFAULT
+#define        PROCESSOR_DEFAULT PROCESSOR_PPC750
 
 /* System V.4 uses register 13 as a pointer to the small data area,
    so it is not available to the normal user.  */
 
-#undef FIXED_R13
 #define FIXED_R13 1
 
-/* System V.4 passes the first 8 floating arguments in registers,
-   instead of the first 13 like AIX does.  */
-#undef FP_ARG_MAX_REG
-#define        FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) \
-                       ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
-
-/* Size of the V.4 varargs area if needed */
+/* Size of the V.4 varargs area if needed.  */
+/* Override rs6000.h definition.  */
 #undef RS6000_VARARGS_AREA
 #define RS6000_VARARGS_AREA ((rs6000_sysv_varargs_p) ? RS6000_VARARGS_SIZE : 0)
 
-/* Override default big endianism */
-#undef  BYTES_BIG_ENDIAN
-#undef  WORDS_BIG_ENDIAN
-#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN)
-#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
+/* Override default big endianism definitions in rs6000.h.  */
+#undef BYTES_BIG_ENDIAN
+#undef WORDS_BIG_ENDIAN
+#define        BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN)
+#define        WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN)
 
 /* Define this to set the endianness to use in libgcc2.c, which can
    not depend on target_flags.  */
@@ -308,88 +303,36 @@ do {                                                                      \
 #define LIBGCC2_WORDS_BIG_ENDIAN 0
 #endif
 
-/* Size of the outgoing register save area */
-#undef RS6000_REG_SAVE
-#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX                       \
-                         || DEFAULT_ABI == ABI_AIX_NODESC)             \
-                        ? (TARGET_64BIT ? 64 : 32)                     \
-                        : 0)
-
-/* Size of the fixed area on the stack.  For AIX, use the standard 6 word
-   area, otherwise use 2 words to store back chain & LR.  */
-#undef RS6000_SAVE_AREA
-#define RS6000_SAVE_AREA \
-  (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC) ? 24 : 8) << (TARGET_64BIT ? 1 : 0))
-
 /* Define cutoff for using external functions to save floating point.
-   Currently on V.4, always use inline stores */
-#undef FP_SAVE_INLINE
+   Currently on V.4, always use inline stores.  */
 #define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
 
-/* Don't generate XCOFF debugging information.  */
-
-#undef XCOFF_DEBUGGING_INFO
-
-/* Don't use the COFF object file format.  */
-
-#undef OBJECT_FORMAT_COFF
-
-/* Don't bother to output .extern pseudo-ops.  They are not needed by
-   ELF assemblers.  */
-
-#undef ASM_OUTPUT_EXTERNAL
-
 /* Put jump tables in read-only memory, rather than in .text.  */
-#undef JUMP_TABLES_IN_TEXT_SECTION
 #define JUMP_TABLES_IN_TEXT_SECTION 0
 
-/* Disable AIX-ism that disables turning -B into -L if the argument specifies a
-   relative file name.  This breaks setting GCC_EXEC_PREFIX to D:\path under
-   Windows.  */
-#undef RELATIVE_PREFIX_NOT_LINKDIR
-
-/* Undefine some things which are defined by the generic svr4.h.  */
-
-#undef ASM_DECLARE_FUNCTION_NAME
-#undef ASM_FILE_END
-#undef ASM_OUTPUT_CONSTRUCTOR
-#undef ASM_OUTPUT_DESTRUCTOR
-#undef ASM_OUTPUT_DEF
-#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-#undef HANDLE_PRAGMA_PACK
-#undef READONLY_DATA_SECTION
-#undef SELECT_SECTION
-
-/* Use the regular svr4 definitions.  */
-
-#include "svr4.h"
-
-/* Prefix and suffix to use to saving floating point */
-#undef SAVE_FP_PREFIX
-#undef SAVE_FP_SUFFIX
+/* Prefix and suffix to use to saving floating point.  */
 #define        SAVE_FP_PREFIX "_savefpr_"
 #define SAVE_FP_SUFFIX "_l"
 
-/* Prefix and suffix to use to restoring floating point */
-#undef RESTORE_FP_PREFIX
-#undef RESTORE_FP_SUFFIX
+/* Prefix and suffix to use to restoring floating point.  */
 #define        RESTORE_FP_PREFIX "_restfpr_"
 #define RESTORE_FP_SUFFIX "_l"
 
 /* Type used for ptrdiff_t, as a string used in a declaration.  */
-#undef PTRDIFF_TYPE
 #define PTRDIFF_TYPE "int"
 
 /* Type used for wchar_t, as a string used in a declaration.  */
+/* Override svr4.h definition.  */
 #undef WCHAR_TYPE
 #define WCHAR_TYPE "long int"
 
 /* Width of wchar_t in bits.  */
+/* Override svr4.h definition.  */
 #undef WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE 32
 
-/* Make int foo : 8 not cause structures to be aligned to an int boundary */
-
+/* Make int foo : 8 not cause structures to be aligned to an int boundary */
+/* Override elfos.h definition.  */
 #undef PCC_BITFIELD_TYPE_MATTERS
 #define        PCC_BITFIELD_TYPE_MATTERS (TARGET_BITFIELD_TYPE)
 
@@ -399,21 +342,13 @@ do {                                                                      \
 #undef STRICT_ALIGNMENT
 #define        STRICT_ALIGNMENT (TARGET_STRICT_ALIGN)
 
-/* Define this macro to be the value 1 if unaligned accesses have a cost
-   many times greater than aligned accesses, for example if they are
-   emulated in a trap handler.  */
-#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN)                     \
-   ((STRICT_ALIGNMENT                                          \
-     || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \
-         && (ALIGN) < 4)) ? 1 : 0)
-
 /* Alignment in bits of the stack boundary.  Note, in order to allow building
    one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
    versions, just use 64 as the stack boundary.  */
 #undef STACK_BOUNDARY
 #define        STACK_BOUNDARY  64
 
-/* Real stack boundary as mandated by the appropriate ABI */
+/* Real stack boundary as mandated by the appropriate ABI */
 #define ABI_STACK_BOUNDARY ((TARGET_EABI) ? 64 : 128)
 
 /* No data type wants to be aligned rounder than this.  */
@@ -426,45 +361,47 @@ do {                                                                      \
 
 /* Use ELF style section commands.  */
 
-#undef TEXT_SECTION_ASM_OP
-#define TEXT_SECTION_ASM_OP    "\t.section\t\".text\""
+#define        TEXT_SECTION_ASM_OP     "\t.section\t\".text\""
 
-#undef DATA_SECTION_ASM_OP
-#define DATA_SECTION_ASM_OP    "\t.section\t\".data\""
+#define        DATA_SECTION_ASM_OP     "\t.section\t\".data\""
 
-#undef BSS_SECTION_ASM_OP
-#define BSS_SECTION_ASM_OP     "\t.section\t\".bss\""
+#define        BSS_SECTION_ASM_OP      "\t.section\t\".bss\""
 
-#undef INIT_SECTION_ASM_OP
-#define INIT_SECTION_ASM_OP "\t.section\t\".init\",\"ax\""
+/* Override elfos.h definition.  */
+#undef INIT_SECTION_ASM_OP
+#define        INIT_SECTION_ASM_OP "\t.section\t\".init\",\"ax\""
 
-#undef FINI_SECTION_ASM_OP
-#define FINI_SECTION_ASM_OP "\t.section\t\".fini\",\"ax\""
+/* Override elfos.h definition.  */
+#undef FINI_SECTION_ASM_OP
+#define        FINI_SECTION_ASM_OP "\t.section\t\".fini\",\"ax\""
 
-#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\""
+#define        TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\""
 
-/* Put PC relative got entries in .got2 */
-#define MINIMAL_TOC_SECTION_ASM_OP \
+/* Put PC relative got entries in .got2 */
+#define        MINIMAL_TOC_SECTION_ASM_OP \
   ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
 
-/* Put relocatable data in .data, not .rodata so initialized pointers can be updated */
+/* Put relocatable data in .data, not .rodata so initialized pointers can be updated.  */
+/* Override elfos.h definition.  */
 #undef CONST_SECTION_ASM_OP
-#define CONST_SECTION_ASM_OP \
+#define        CONST_SECTION_ASM_OP \
   ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".data\"\t# .rodata" : "\t.section\t\".rodata\"")
 
 
-#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\""
-#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\""
-#define SBSS_SECTION_ASM_OP \
+#define        SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\""
+#define        SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\""
+#define        SBSS_SECTION_ASM_OP \
   ((DEFAULT_ABI == ABI_SOLARIS) ? "\t.section\t\".sbss\",\"aw\"" : "\t.section\t\".sbss\",\"aw\",@nobits")
 
 
 /* Besides the usual ELF sections, we need a toc section.  */
-#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc, in_sdata, in_sdata2, in_sbss, in_init, in_fini
+/* Override elfos.h definition.  */
+#undef EXTRA_SECTIONS
+#define        EXTRA_SECTIONS in_const, in_ctors, in_dtors, in_toc, in_sdata, in_sdata2, in_sbss, in_init, in_fini
 
-#undef EXTRA_SECTION_FUNCTIONS
-#define EXTRA_SECTION_FUNCTIONS                                                \
+/* Override elfos.h definition.  */
+#undef EXTRA_SECTION_FUNCTIONS
+#define        EXTRA_SECTION_FUNCTIONS                                         \
   CONST_SECTION_FUNCTION                                               \
   CTORS_SECTION_FUNCTION                                               \
   DTORS_SECTION_FUNCTION                                               \
@@ -475,17 +412,14 @@ do {                                                                      \
   INIT_SECTION_FUNCTION                                                        \
   FINI_SECTION_FUNCTION
 
-extern void toc_section (), sdata_section (), sdata2_section ();
-extern void sbss_section ();
-
-#define TOC_SECTION_FUNCTION                                           \
+#define        TOC_SECTION_FUNCTION                                            \
 void                                                                   \
 toc_section ()                                                         \
 {                                                                      \
   if (in_section != in_toc)                                            \
     {                                                                  \
       in_section = in_toc;                                             \
-      if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)            \
+      if (DEFAULT_ABI == ABI_AIX                                       \
          && TARGET_MINIMAL_TOC                                         \
          && !TARGET_RELOCATABLE)                                       \
        {                                                               \
@@ -506,8 +440,7 @@ toc_section ()                                                              \
          else                                                          \
            fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
        }                                                               \
-      else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)       \
-              && !TARGET_RELOCATABLE)                                  \
+      else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)          \
        fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);             \
       else                                                             \
        {                                                               \
@@ -522,7 +455,7 @@ toc_section ()                                                              \
     }                                                                  \
 }
 
-#define SDATA_SECTION_FUNCTION                                         \
+#define        SDATA_SECTION_FUNCTION                                          \
 void                                                                   \
 sdata_section ()                                                       \
 {                                                                      \
@@ -533,7 +466,7 @@ sdata_section ()                                                    \
     }                                                                  \
 }
 
-#define SDATA2_SECTION_FUNCTION                                                \
+#define        SDATA2_SECTION_FUNCTION                                         \
 void                                                                   \
 sdata2_section ()                                                      \
 {                                                                      \
@@ -544,7 +477,7 @@ sdata2_section ()                                                   \
     }                                                                  \
 }
 
-#define SBSS_SECTION_FUNCTION                                          \
+#define        SBSS_SECTION_FUNCTION                                           \
 void                                                                   \
 sbss_section ()                                                                \
 {                                                                      \
@@ -555,7 +488,7 @@ sbss_section ()                                                             \
     }                                                                  \
 }
 
-#define INIT_SECTION_FUNCTION                                          \
+#define        INIT_SECTION_FUNCTION                                           \
 void                                                                   \
 init_section ()                                                                \
 {                                                                      \
@@ -566,7 +499,7 @@ init_section ()                                                             \
     }                                                                  \
 }
 
-#define FINI_SECTION_FUNCTION                                          \
+#define        FINI_SECTION_FUNCTION                                           \
 void                                                                   \
 fini_section ()                                                                \
 {                                                                      \
@@ -586,18 +519,18 @@ fini_section ()                                                           \
    Do not define this macro if you put all constants in the read-only
    data section.  */
 
-extern void rs6000_select_rtx_section (), rs6000_select_section ();
-
-#undef SELECT_RTX_SECTION
-#define SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X)
+/* Override elfos.h definition.  */
+#undef SELECT_RTX_SECTION
+#define        SELECT_RTX_SECTION(MODE, X) rs6000_select_rtx_section (MODE, X)
 
 /* A C statement or statements to switch to the appropriate
    section for output of DECL.  DECL is either a `VAR_DECL' node
    or a constant of some sort.  RELOC indicates whether forming
    the initial value of DECL requires link-time relocations.  */
 
-#undef SELECT_SECTION
-#define SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC)
+/* Override elfos.h definition.  */
+#undef SELECT_SECTION
+#define        SELECT_SECTION(DECL,RELOC) rs6000_select_section (DECL, RELOC)
 
 /* Return non-zero if this entry is to be written into the constant pool
    in a special way.  We do so if this is a SYMBOL_REF, LABEL_REF or a CONST
@@ -611,7 +544,7 @@ extern void rs6000_select_rtx_section (), rs6000_select_section ();
    allow floating point constants in the TOC if -mrelocatable.  */
 
 #undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
-#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X)                             \
+#define        ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X)                              \
   (TARGET_TOC                                                          \
    && (GET_CODE (X) == SYMBOL_REF                                      \
        || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS     \
@@ -634,14 +567,14 @@ extern void rs6000_select_rtx_section (), rs6000_select_section ();
 
 extern int rs6000_pic_labelno;
 
+/* Override elfos.h definition.  */
 #undef ASM_DECLARE_FUNCTION_NAME
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                    \
   do {                                                                 \
-    const char *orig_name;                                             \
     const char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long";         \
-    STRIP_NAME_ENCODING (orig_name, NAME);                             \
                                                                        \
-    if (TARGET_RELOCATABLE && (get_pool_size () != 0 || profile_flag)) \
+    if (TARGET_RELOCATABLE && (get_pool_size () != 0 || profile_flag)  \
+       && uses_TOC())                                                  \
       {                                                                        \
        char buf[256];                                                  \
        const char *buf_ptr;                                            \
@@ -649,22 +582,27 @@ extern int rs6000_pic_labelno;
        ASM_OUTPUT_INTERNAL_LABEL (FILE, "LCL", rs6000_pic_labelno);    \
                                                                        \
        ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);                  \
-       STRIP_NAME_ENCODING (buf_ptr, buf);                             \
-       fprintf (FILE, "\t%s %s-", init_ptr, buf_ptr);                  \
-                                                                       \
+       fprintf (FILE, "\t%s ", init_ptr);                              \
+       assemble_name (FILE, buf);                                      \
+       putc ('-', FILE);                                               \
        ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);   \
-       fprintf (FILE, "%s\n", buf_ptr);                                \
+       assemble_name (FILE, buf);                                      \
+       putc ('\n', FILE);                                              \
       }                                                                        \
                                                                        \
-    fprintf (FILE, "\t%s\t %s,", TYPE_ASM_OP, orig_name);              \
+    fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                            \
+    assemble_name (FILE, NAME);                                                \
+    putc (',', FILE);                                                  \
     fprintf (FILE, TYPE_OPERAND_FMT, "function");                      \
     putc ('\n', FILE);                                                 \
     ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));                     \
                                                                        \
-    if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)               \
+    if (DEFAULT_ABI == ABI_AIX)                                                \
       {                                                                        \
-       const char *desc_name = orig_name;                              \
+       const char *desc_name, *orig_name;                              \
                                                                        \
+        STRIP_NAME_ENCODING (orig_name, NAME);                         \
+        desc_name = orig_name;                                         \
        while (*desc_name == '.')                                       \
          desc_name++;                                                  \
                                                                        \
@@ -679,23 +617,72 @@ extern int rs6000_pic_labelno;
          fprintf (FILE, "\t%s 0\n", init_ptr);                         \
        fprintf (FILE, "\t.previous\n");                                \
       }                                                                        \
-    fprintf (FILE, "%s:\n", orig_name);                                        \
+    ASM_OUTPUT_LABEL (FILE, NAME);                                     \
   } while (0)
 
+/* A C compound statement that outputs the assembler code for a thunk function,
+    used to implement C++ virtual function calls with multiple inheritance.  The
+    thunk acts as a wrapper around a virtual function, adjusting the implicit
+    object parameter before handing control off to the real function.
+
+    First, emit code to add the integer DELTA to the location that contains the
+    incoming first argument.  Assume that this argument contains a pointer, and
+    is the one used to pass the this' pointer in C++.  This is the incoming
+    argument *before* the function prologue, e.g. %o0' on a sparc.  The
+    addition must preserve the values of all other incoming arguments.
+
+    After the addition, emit code to jump to FUNCTION, which is a
+    FUNCTION_DECL'.  This is a direct pure jump, not a call, and does not touch
+    the return address.  Hence returning from FUNCTION will return to whoever
+    called the current thunk'.
+
+    The effect must be as if FUNCTION had been called directly with the adjusted
+    first argument.  This macro is responsible for emitting all of the code for
+    a thunk function; FUNCTION_PROLOGUE' and FUNCTION_EPILOGUE' are not
+    invoked.
+
+    The THUNK_FNDECL is redundant.  (DELTA and FUNCTION have already been
+    extracted from it.)  It might possibly be useful on some targets, but
+    probably not.
+
+    If you do not define this macro, the target-independent code in the C++
+    frontend will generate a less efficient heavyweight thunk that calls
+    FUNCTION instead of jumping to it.  The generic approach does not support
+    varargs.  */
+
+#define        ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
+  output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
+
 /* How to renumber registers for dbx and gdb.  */
 
-#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
+#define        DBX_REGISTER_NUMBER(REGNO) (REGNO)
+
+/* The USER_LABEL_PREFIX stuff is affected by the -fleading-underscore
+   flag.  The LOCAL_LABEL_PREFIX variable is used by dbxelf.h.  */
+
+#define        LOCAL_LABEL_PREFIX "."
+#define        USER_LABEL_PREFIX ""
 
 /* svr4.h overrides ASM_OUTPUT_INTERNAL_LABEL.  */
 
-#undef ASM_OUTPUT_INTERNAL_LABEL_PREFIX
-#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX)  \
-  fprintf (FILE, ".%s", PREFIX)
+#define        ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX)   \
+  asm_fprintf (FILE, "%L%s", PREFIX)
+
+#define        ASM_OUTPUT_LABEL(FILE,NAME)     \
+  (assemble_name (FILE, NAME), fputs (":\n", FILE))
+
+/* This is how to output a command to make the user-level label named NAME
+   defined for reference from other files.  */
+
+#define        ASM_GLOBALIZE_LABEL(FILE,NAME)  \
+  do { fputs ("\t.globl ", FILE);      \
+       assemble_name (FILE, NAME); putc ('\n', FILE);} while (0)
 
 /* This is how to allocate empty space in some section.  Use .space
    instead of .zero because the Solaris PowerPC assembler doesn't
    like it, and gas accepts either syntax.  */
 
+/* Override elfos.h definition.  */
 #undef SKIP_ASM_OP
 #define SKIP_ASM_OP    ".space"
 
@@ -704,16 +691,13 @@ extern int rs6000_pic_labelno;
    the linker seems to want the alignment of data objects
    to depend on their types.  We do exactly that here.  */
 
-#ifndef LOCAL_ASM_OP
-#define LOCAL_ASM_OP   ".local"
-#endif
+#define        LOCAL_ASM_OP    ".local"
 
-#ifndef LCOMM_ASM_OP
-#define LCOMM_ASM_OP   ".lcomm"
-#endif
+#define        LCOMM_ASM_OP    ".lcomm"
 
-#undef ASM_OUTPUT_ALIGNED_LOCAL
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)              \
+/* Override elfos.h definition.  */
+#undef ASM_OUTPUT_ALIGNED_LOCAL
+#define        ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)               \
 do {                                                                   \
   if (rs6000_sdata != SDATA_NONE && (SIZE) > 0                         \
       && (SIZE) <= g_switch_value)                                     \
@@ -737,17 +721,18 @@ do {                                                                      \
     }                                                                  \
 } while (0)
 
-/* Describe how to emit uninitialized external linkage items  */
-#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)          \
+/* Describe how to emit uninitialized external linkage items.  */
+#define        ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)           \
 do {                                                                   \
   ASM_GLOBALIZE_LABEL (FILE, NAME);                                    \
   ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN);                  \
 } while (0)
 
-/* Switch  Recognition by gcc.c.  Add -G xx support */
+/* Switch  Recognition by gcc.c.  Add -G xx support */
 
-#undef SWITCH_TAKES_ARG
-#define SWITCH_TAKES_ARG(CHAR)                                         \
+/* Override svr4.h definition.  */
+#undef SWITCH_TAKES_ARG
+#define        SWITCH_TAKES_ARG(CHAR)                                          \
   ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o'                     \
    || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u'                  \
    || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x'                  \
@@ -755,22 +740,26 @@ do {                                                                      \
    || (CHAR) == 'B' || (CHAR) == 'b' || (CHAR) == 'G')
 
 /* Output .file.  */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE)                                           \
+/* Override elfos.h definition.  */
+#undef ASM_FILE_START
+#define        ASM_FILE_START(FILE)                                            \
 do {                                                                   \
   output_file_directive ((FILE), main_input_filename);                 \
   rs6000_file_start (FILE, TARGET_CPU_DEFAULT);                                \
 } while (0)
 
 
+extern int fixuplabelno;
+
 /* This is how to output an assembler line defining an `int' constant.
    For -mrelocatable, we mark all addresses that need to be fixed up
    in the .fixup section.  */
+/* Override rs6000.h definition.  */
 #undef ASM_OUTPUT_INT
 #define ASM_OUTPUT_INT(FILE,VALUE)                                     \
 do {                                                                   \
   static int recurse = 0;                                              \
-  if ((TARGET_RELOCATABLE || flag_pic)                                 \
+  if (TARGET_RELOCATABLE                                               \
       && in_section != in_toc                                          \
       && in_section != in_text                                         \
       && in_section != in_ctors                                                \
@@ -780,29 +769,28 @@ do {                                                                      \
       && GET_CODE (VALUE) != CONST_DOUBLE                              \
       && CONSTANT_P (VALUE))                                           \
     {                                                                  \
-      static int labelno = 0;                                          \
       char buf[256];                                                   \
-      const char *p;                                                   \
                                                                        \
       recurse = 1;                                                     \
-      ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", labelno++);             \
-      STRIP_NAME_ENCODING (p, buf);                                    \
-      fprintf (FILE, "%s:\n", p);                                      \
+      ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);          \
+      fixuplabelno++;                                                  \
+      ASM_OUTPUT_LABEL (FILE, buf);                                    \
       fprintf (FILE, "\t.long (");                                     \
       output_addr_const (FILE, (VALUE));                               \
       fprintf (FILE, ")@fixup\n");                                     \
-      fprintf (FILE, "\t.section\t\".fixup\",\"aw\"\n");                       \
+      fprintf (FILE, "\t.section\t\".fixup\",\"aw\"\n");               \
       ASM_OUTPUT_ALIGN (FILE, 2);                                      \
-      fprintf (FILE, "\t.long\t%s\n", p);                              \
-      fprintf (FILE, "\t.previous\n");                                 \
+      fprintf (FILE, "\t.long\t");                                     \
+      assemble_name (FILE, buf);                                       \
+      fprintf (FILE, "\n\t.previous\n");                               \
       recurse = 0;                                                     \
     }                                                                  \
-  /* Remove initial .'s to turn a -mcall-aixdesc or -mcall-nt function \
+  /* Remove initial .'s to turn a -mcall-aixdesc function              \
      address into the address of the descriptor, not the function      \
      itself.  */                                                       \
   else if (GET_CODE (VALUE) == SYMBOL_REF                              \
           && XSTR (VALUE, 0)[0] == '.'                                 \
-          && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT))        \
+          && DEFAULT_ABI == ABI_AIX)                                   \
     {                                                                  \
       const char *name = XSTR (VALUE, 0);                              \
       while (*name == '.')                                             \
@@ -818,34 +806,66 @@ do {                                                                      \
     }                                                                  \
 } while (0)
 
+/* This is how to output an assembler line defining an address 
+   constant for the dwarf call unwinding information.
+   For -mrelocatable, we mark all addresses that need to be fixed up
+   in the .fixup section.  */
+
+#define        ASM_OUTPUT_DWARF_ADDR(FILE,LABEL)                               \
+do {                                                                   \
+  if (TARGET_RELOCATABLE)                                              \
+    {                                                                  \
+      char buf[256];                                                   \
+      const char *p;                                                   \
+                                                                       \
+      ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);          \
+      fixuplabelno++;                                                  \
+      ASM_OUTPUT_LABEL (FILE, buf);                                    \
+      fprintf (FILE, "\t.%dbyte\t", POINTER_SIZE / BITS_PER_UNIT);     \
+      assemble_name (FILE, LABEL);                                     \
+      fprintf (FILE, "\n");                                            \
+      fprintf (FILE, "\t.section \".fixup\",\"aw\"\n");                        \
+      ASM_OUTPUT_ALIGN (FILE, 2);                                      \
+      fprintf (FILE, "\t.long\t");                                     \
+      assemble_name (FILE, buf);                                       \
+      fprintf (FILE, "\n\t.previous\n");                               \
+    }                                                                  \
+  else                                                                 \
+    {                                                                  \
+      fprintf (FILE, "\t.%dbyte\t", POINTER_SIZE / BITS_PER_UNIT);     \
+      assemble_name (FILE, LABEL);                                     \
+    }                                                                  \
+} while (0)
+
 /* This is the end of what might become sysv4.h.  */
 
 /* Allow stabs and dwarf, for now, make stabs the default debugging type,
-   not dwarf since G++ doesn't support dwarf. */
+   not dwarf since G++ doesn't support dwarf.  */
 #undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+#define        PREFERRED_DEBUGGING_TYPE DBX_DEBUG
 
 #define        DBX_DEBUGGING_INFO
-#define        DWARF_DEBUGGING_INFO
 
 /* If we are referencing a function that is static or is known to be
    in this file, make the SYMBOL_REF special.  We can use this to indicate
    that we can branch to this function without emitting a no-op after the
-   call.  For real AIX and NT calling sequences, we also replace the
+   call.  For real AIX calling sequences, we also replace the
    function name with the real name (1 or 2 leading .'s), rather than
    the function descriptor name.  This saves a lot of overriding code
-   to readd the prefixes.  */
+   to read the prefixes.  */
 
 #undef ENCODE_SECTION_INFO
-#define ENCODE_SECTION_INFO(DECL) rs6000_encode_section_info (DECL)
+#define        ENCODE_SECTION_INFO(DECL) rs6000_encode_section_info (DECL)
 
-extern void rs6000_encode_section_info ();
+/* The ELF version doesn't encode [DS] or whatever at the end of symbols.  */
+
+#define        RS6000_OUTPUT_BASENAME(FILE, NAME)      \
+    assemble_name (FILE, NAME)
 
 /* This macro gets just the user-specified name
    out of the string in a SYMBOL_REF.  Discard
-   a leading * or @. */
-#undef  STRIP_NAME_ENCODING
-#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME)                           \
+   a leading * or @.  */
+#define        STRIP_NAME_ENCODING(VAR,SYMBOL_NAME)                            \
 do {                                                                   \
   const char *_name = SYMBOL_NAME;                                     \
   while (*_name == '*' || *_name == '@')                               \
@@ -856,32 +876,36 @@ do {                                                                      \
 /* This is how to output a reference to a user-level label named NAME.
    `assemble_name' uses this.  */
 
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-do {                                                                   \
-  const char *_name = NAME;                                            \
-  while (*_name == '*' || *_name == '@')                               \
-    _name++;                                                           \
-  fputs (_name, FILE);                                                 \
+/* Override elfos.h definition.  */
+#undef ASM_OUTPUT_LABELREF
+#define        ASM_OUTPUT_LABELREF(FILE,NAME)          \
+do {                                           \
+  const char *_name = NAME;                    \
+  if (*_name == '@')                           \
+    _name++;                                   \
+                                               \
+  if (*_name == '*')                           \
+    fprintf (FILE, "%s", _name + 1);           \
+  else                                         \
+    asm_fprintf (FILE, "%U%s", _name);         \
 } while (0)
 
-/*
- * Switch into a generic section.
- *
- * We make the section read-only and executable for a function decl,
- * read-only for a const data decl, and writable for a non-const data decl.
- *
- * If the section has already been defined, we must not
- * emit the attributes here. The SVR4 assembler does not
- * recognize section redefinitions.
- * If DECL is NULL, no attributes are emitted.
- *
- * Note, Solaris as doesn't like @nobits, and gas can handle .sbss without
- * needing @nobits.
- */
+/* Switch into a generic section.
+
+   We make the section read-only and executable for a function decl,
+   read-only for a const data decl, and writable for a non-const data decl.
+
+   If the section has already been defined, we must not
+   emit the attributes here. The SVR4 assembler does not
+   recognize section redefinitions.
+   If DECL is NULL, no attributes are emitted.
+
+   Note, Solaris as doesn't like @nobits, and gas can handle .sbss without
+   needing @nobits.  */
 
+/* Override elfos.h definition.  */
 #undef ASM_OUTPUT_SECTION_NAME
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)               \
+#define        ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)                \
 do {                                                                   \
   static struct section_info                                           \
     {                                                                  \
@@ -923,8 +947,9 @@ do {                                                                        \
     }                                                                  \
 } while (0)
 
-#undef ASM_OUTPUT_CONSTRUCTOR
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME)                              \
+/* Override elfos.h definition.  */
+#undef ASM_OUTPUT_CONSTRUCTOR
+#define        ASM_OUTPUT_CONSTRUCTOR(FILE,NAME)                               \
   do {                                                                 \
     if (DEFAULT_ABI != ABI_SOLARIS)                                    \
       {                                                                        \
@@ -943,8 +968,9 @@ do {                                                                        \
 
 /* A C statement (sans semicolon) to output an element in the table of
    global destructors.  */
-#undef ASM_OUTPUT_DESTRUCTOR
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME)                                       \
+/* Override elfos.h definition.  */
+#undef ASM_OUTPUT_DESTRUCTOR
+#define        ASM_OUTPUT_DESTRUCTOR(FILE,NAME)                                \
   do {                                                                 \
     if (DEFAULT_ABI != ABI_SOLARIS)                                    \
       {                                                                        \
@@ -968,16 +994,17 @@ do {                                                                      \
 
 /* This is the end of what might become sysv4dbx.h.  */
 
-#undef TARGET_VERSION
-#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
+/* Override rs6000.h definition.  */
+#undef TARGET_VERSION
+#define        TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
 \f
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES \
+#define        CPP_PREDEFINES \
   "-DPPC -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(powerpc) -Amachine(powerpc)"
 
-/* Pass various options to the assembler */
-#undef ASM_SPEC
-#define ASM_SPEC "%(asm_cpu) \
+/* Pass various options to the assembler.  */
+/* Override svr4.h definition.  */
+#undef ASM_SPEC
+#define        ASM_SPEC "%(asm_cpu) \
 %{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
 %{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
 %{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
@@ -987,34 +1014,26 @@ do {                                                                     \
     %{mcall-solaris: -mlittle -msolaris} \
     %{mcall-linux: -mbig} }}}}"
 
-#ifndef CC1_ENDIAN_BIG_SPEC
-#define CC1_ENDIAN_BIG_SPEC ""
-#endif
+#define        CC1_ENDIAN_BIG_SPEC ""
 
-#ifndef CC1_ENDIAN_LITTLE_SPEC
-#define CC1_ENDIAN_LITTLE_SPEC "\
+#define        CC1_ENDIAN_LITTLE_SPEC "\
 %{!mstrict-align: %{!mno-strict-align: \
        -mstrict-align \
 }}"
-#endif
 
-#ifndef CC1_ENDIAN_DEFAULT_SPEC
-#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big_spec)"
-#endif
+#define        CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big_spec)"
 
-#undef CC1_SPEC
-/* Pass -G xxx to the compiler and set correct endian mode */
-#define CC1_SPEC "%{G*} \
+/* Pass -G xxx to the compiler and set correct endian mode.  */
+#define        CC1_SPEC "%{G*} \
 %{mlittle: %(cc1_endian_little)} %{!mlittle: %{mlittle-endian: %(cc1_endian_little)}} \
 %{mbig: %(cc1_endian_big)} %{!mbig: %{mbig-endian: %(cc1_endian_big)}} \
 %{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
-    %{mcall-nt: -mlittle %(cc1_endian_little) } \
     %{mcall-aixdesc: -mbig %(cc1_endian_big) } \
     %{mcall-solaris: -mlittle %(cc1_endian_little) } \
     %{mcall-linux: -mbig %(cc1_endian_big) } \
-    %{!mcall-nt: %{!mcall-aixdesc: %{!mcall-solaris: %{!mcall-linux: \
+    %{!mcall-aixdesc: %{!mcall-solaris: %{!mcall-linux: \
            %(cc1_endian_default) \
-    }}}} \
+    }}} \
 }}}} \
 %{mcall-solaris: -mregnames } \
 %{mno-sdata: -msdata=none } \
@@ -1027,8 +1046,7 @@ do {                                                                      \
 %{mno-sdata: -msdata=none} \
 %{profile: -p}"
 
-/* Don't put -Y P,<path> for cross compilers */
-#undef LINK_PATH_SPEC
+/* Don't put -Y P,<path> for cross compilers.  */
 #ifndef CROSS_COMPILE
 #define LINK_PATH_SPEC "\
 %{!R*:%{L*:-R %*}} \
@@ -1045,8 +1063,7 @@ do {                                                                      \
 #define LINK_PATH_SPEC ""
 #endif
 
-/* Default starting address if specified */
-#ifndef LINK_START_SPEC
+/* Default starting address if specified.  */
 #define LINK_START_SPEC "\
 %{mads: %(link_start_ads) } \
 %{myellowknife: %(link_start_yellowknife) } \
@@ -1055,14 +1072,12 @@ do {                                                                    \
 %{mcall-linux: %(link_start_linux) } \
 %{mcall-solaris: %(link_start_solaris) } \
 %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(link_start_default) }}}}}}"
-#endif
 
-#ifndef        LINK_START_DEFAULT_SPEC
 #define LINK_START_DEFAULT_SPEC ""
-#endif
 
-#undef LINK_SPEC
-#define LINK_SPEC "\
+/* Override svr4.h definition.  */
+#undef LINK_SPEC
+#define        LINK_SPEC "\
 %{h*} %{v:-V} %{G*} \
 %{Wl,*:%*} %{YP,*} %{R*} \
 %{Qy:} %{!Qn:-Qy} \
@@ -1076,7 +1091,6 @@ do {                                                                      \
 #define NO_SHARED_LIB_SUPPORT
 #endif
 
-#undef  LINK_SHLIB_SPEC
 #ifndef NO_SHARED_LIB_SUPPORT
 /* Shared libraries are default.  */
 #define LINK_SHLIB_SPEC "\
@@ -1097,13 +1111,13 @@ do {                                                                    \
 #endif
 
 /* Override the default target of the linker.  */
-#undef LINK_TARGET_SPEC
 #define        LINK_TARGET_SPEC "\
 %{mlittle: -oformat elf32-powerpcle } %{mlittle-endian: -oformat elf32-powerpcle } \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: %{mcall-solaris: -oformat elf32-powerpcle}}}}}"
+%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
+    %{mcall-solaris: -oformat elf32-powerpcle} \
+  }}}}"
 
-/* Any specific OS flags */
-#ifndef LINK_OS_SPEC
+/* Any specific OS flags.  */
 #define LINK_OS_SPEC "\
 %{mads: %(link_os_ads) } \
 %{myellowknife: %(link_os_yellowknife) } \
@@ -1112,39 +1126,39 @@ do {                                                                    \
 %{mcall-linux: %(link_os_linux) } \
 %{mcall-solaris: %(link_os_solaris) } \
 %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(link_os_default) }}}}}}"
-#endif
 
-#ifndef        LINK_OS_DEFAULT_SPEC
 #define LINK_OS_DEFAULT_SPEC ""
-#endif
 
-#undef CPP_SYSV_SPEC
 #define CPP_SYSV_SPEC \
 "%{mrelocatable*: -D_RELOCATABLE} \
 %{fpic: -D__PIC__=1 -D__pic__=1} \
 %{!fpic: %{fPIC: -D__PIC__=2 -D__pic__=2}} \
-%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
+%{mcall-sysv: -D_CALL_SYSV} \
 %{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
-%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: %(cpp_sysv_default) }}}} \
-%{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT}"
+%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %(cpp_sysv_default) }}} \
+%{msoft-float: -D_SOFT_FLOAT} \
+%{!msoft-float: %{!mhard-float: \
+    %{mcpu=401: -D_SOFT_FLOAT} \
+    %{mcpu=403: -D_SOFT_FLOAT} \
+    %{mcpu=ec603e: -D_SOFT_FLOAT} \
+    %{mcpu=801: -D_SOFT_FLOAT} \
+    %{mcpu=821: -D_SOFT_FLOAT} \
+    %{mcpu=823: -D_SOFT_FLOAT} \
+    %{mcpu=860: -D_SOFT_FLOAT} \
+    %{!mcpu*: %(cpp_float_default) }}}"
+
+/* Whether floating point is disabled by default.  */
+#define        CPP_FLOAT_DEFAULT_SPEC ""
 
-#undef CPP_SYSV_DEFAULT_SPEC
 #define        CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV"
 
-#ifndef CPP_ENDIAN_BIG_SPEC
 #define CPP_ENDIAN_BIG_SPEC "-D_BIG_ENDIAN -D__BIG_ENDIAN__ -Amachine(bigendian)"
-#endif
 
-#ifndef CPP_ENDIAN_LITTLE_SPEC
 #define CPP_ENDIAN_LITTLE_SPEC "-D_LITTLE_ENDIAN -D__LITTLE_ENDIAN__ -Amachine(littleendian)"
-#endif
 
-#ifndef CPP_ENDIAN_SOLARIS_SPEC
 #define CPP_ENDIAN_SOLARIS_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)"
-#endif
 
 /* For solaris, don't define _LITTLE_ENDIAN, it conflicts with a header file.  */
-#undef CPP_ENDIAN_SPEC
 #define        CPP_ENDIAN_SPEC \
 "%{mlittle: %(cpp_endian_little) } \
 %{mlittle-endian: %(cpp_endian_little) } \
@@ -1152,16 +1166,15 @@ do {                                                                    \
 %{mbig-endian: %(cpp_endian_big) } \
 %{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
     %{mcall-solaris: %(cpp_endian_solaris) } \
-    %{mcall-nt: %(cpp_endian_little) } \
     %{mcall-linux: %(cpp_endian_big) } \
     %{mcall-aixdesc:  %(cpp_endian_big) } \
-    %{!mcall-solaris: %{!mcall-linux: %{!mcall-nt: %{!mcall-aixdesc: %(cpp_endian_default) }}}}}}}}"
+    %{!mcall-solaris: %{!mcall-linux: %{!mcall-aixdesc: %(cpp_endian_default) }}}}}}}"
 
-#undef CPP_ENDIAN_DEFAULT_SPEC
 #define        CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_big)"
 
-#undef CPP_SPEC
-#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian) %(cpp_cpu) \
+/* Override rs6000.h definition.  */
+#undef CPP_SPEC
+#define        CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian) %(cpp_cpu) \
 %{mads: %(cpp_os_ads) } \
 %{myellowknife: %(cpp_os_yellowknife) } \
 %{mmvme: %(cpp_os_mvme) } \
@@ -1170,11 +1183,10 @@ do {                                                                    \
 %{mcall-solaris: %(cpp_os_solaris) } \
 %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(cpp_os_default) }}}}}}"
 
-#ifndef CPP_OS_DEFAULT_SPEC
-#define CPP_OS_DEFAULT_SPEC ""
-#endif
+#define        CPP_OS_DEFAULT_SPEC ""
 
-#undef  STARTFILE_SPEC
+/* Override svr4.h definition.  */
+#undef STARTFILE_SPEC
 #define        STARTFILE_SPEC "\
 %{mads: %(startfile_ads) } \
 %{myellowknife: %(startfile_yellowknife) } \
@@ -1184,9 +1196,9 @@ do {                                                                      \
 %{mcall-solaris: %(startfile_solaris) } \
 %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(startfile_default) }}}}}}"
 
-#undef STARTFILE_DEFAULT_SPEC
 #define        STARTFILE_DEFAULT_SPEC ""
 
+/* Override svr4.h definition.  */
 #undef LIB_SPEC
 #define        LIB_SPEC "\
 %{mads: %(lib_ads) } \
@@ -1197,13 +1209,13 @@ do {                                                                    \
 %{mcall-solaris: %(lib_solaris) } \
 %{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(lib_default) }}}}}}"
 
+/* Override rs6000.h definition.  */
 #undef LIBGCC_SPEC
 #define        LIBGCC_SPEC "libgcc.a%s"
 
-#ifndef LIB_DEFAULT_SPEC
 #define LIB_DEFAULT_SPEC ""
-#endif
 
+/* Override svr4.h definition.  */
 #undef ENDFILE_SPEC
 #define        ENDFILE_SPEC "\
 %{mads: ecrtn.o%s} \
@@ -1212,113 +1224,64 @@ do {                                                                   \
 %{msim: ecrtn.o%s} \
 %{mcall-linux: %(endfile_linux) } \
 %{mcall-solaris: scrtn.o%s} \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(endfile_default) }}}}}}"
+%{mvxworks: %(endfile_vxworks) } \
+%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %{!mvxworks: %(endfile_default) }}}}}}}"
 
-#undef ENDFILE_DEFAULT_SPEC
 #define        ENDFILE_DEFAULT_SPEC ""
 
 /* Motorola ADS support.  */
-#ifndef        LIB_ADS_SPEC
 #define LIB_ADS_SPEC "--start-group -lads -lc --end-group"
-#endif
 
-#ifndef        STARTFILE_ADS_SPEC
 #define        STARTFILE_ADS_SPEC "ecrti.o%s crt0.o%s"
-#endif
 
-#ifndef        ENDFILE_ADS_SPEC
 #define        ENDFILE_ADS_SPEC "ecrtn.o%s"
-#endif
 
-#ifndef LINK_START_ADS_SPEC
 #define LINK_START_ADS_SPEC "-T ads.ld%s"
-#endif
 
-#ifndef LINK_OS_ADS_SPEC
 #define LINK_OS_ADS_SPEC ""
-#endif
 
-#ifndef CPP_OS_ADS_SPEC
 #define CPP_OS_ADS_SPEC ""
-#endif
 
 /* Motorola Yellowknife support.  */
-#ifndef        LIB_YELLOWKNIFE_SPEC
 #define LIB_YELLOWKNIFE_SPEC "--start-group -lyk -lc --end-group"
-#endif
 
-#ifndef        STARTFILE_YELLOWKNIFE_SPEC
 #define        STARTFILE_YELLOWKNIFE_SPEC "ecrti.o%s crt0.o%s"
-#endif
 
-#ifndef        ENDFILE_YELLOWKNIFE_SPEC
 #define        ENDFILE_YELLOWKNIFE_SPEC "ecrtn.o%s"
-#endif
 
-#ifndef LINK_START_YELLOWKNIFE_SPEC
 #define LINK_START_YELLOWKNIFE_SPEC "-T yellowknife.ld%s"
-#endif
 
-#ifndef LINK_OS_YELLOWKNIFE_SPEC
 #define LINK_OS_YELLOWKNIFE_SPEC ""
-#endif
 
-#ifndef CPP_OS_YELLOWKNIFE_SPEC
 #define CPP_OS_YELLOWKNIFE_SPEC ""
-#endif
 
 /* Motorola MVME support.  */
-#ifndef        LIB_MVME_SPEC
 #define LIB_MVME_SPEC "--start-group -lmvme -lc --end-group"
-#endif
 
-#ifndef        STARTFILE_MVME_SPEC
 #define        STARTFILE_MVME_SPEC "ecrti.o%s crt0.o%s"
-#endif
 
-#ifndef        ENDFILE_MVME_SPEC
 #define        ENDFILE_MVME_SPEC "ecrtn.o%s"
-#endif
 
-#ifndef LINK_START_MVME_SPEC
 #define LINK_START_MVME_SPEC "%{!Wl,-T*: %{!T*: -Ttext 0x40000}}"
-#endif
 
-#ifndef LINK_OS_MVME_SPEC
 #define LINK_OS_MVME_SPEC ""
-#endif
 
-#ifndef CPP_OS_MVME_SPEC
 #define CPP_OS_MVME_SPEC ""
-#endif
 
 /* PowerPC simulator based on netbsd system calls support.  */
-#ifndef        LIB_SIM_SPEC
 #define LIB_SIM_SPEC "--start-group -lsim -lc --end-group"
-#endif
 
-#ifndef        STARTFILE_SIM_SPEC
 #define        STARTFILE_SIM_SPEC "ecrti.o%s sim-crt0.o%s"
-#endif
 
-#ifndef        ENDFILE_SIM_SPEC
 #define        ENDFILE_SIM_SPEC "ecrtn.o%s"
-#endif
 
-#ifndef LINK_START_SIM_SPEC
 #define LINK_START_SIM_SPEC "-Ttext 0x10000074"
-#endif
 
-#ifndef LINK_OS_SIM_SPEC
 #define LINK_OS_SIM_SPEC ""
-#endif
 
-#ifndef CPP_OS_SIM_SPEC
 #define CPP_OS_SIM_SPEC ""
-#endif
 
 /* GNU/Linux support.  */
-#ifndef        LIB_LINUX_SPEC
 #ifdef USE_GNULIBC_1
 #define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \
 %{!mnewlib: -lc }"
@@ -1327,30 +1290,20 @@ do {                                                                    \
 %{!mnewlib: %{shared:-lc} %{!shared: %{pthread:-lpthread } \
 %{profile:-lc_p} %{!profile:-lc}}}"
 #endif
-#endif
 
-#ifndef        STARTFILE_LINUX_SPEC
 #define        STARTFILE_LINUX_SPEC "\
 %{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
 %{mnewlib: ecrti.o%s} \
 %{!mnewlib: crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-#endif
 
-#ifndef        ENDFILE_LINUX_SPEC
 #define        ENDFILE_LINUX_SPEC "\
 %{mnewlib: ecrtn.o%s} \
 %{!mnewlib: %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s}"
-#endif
 
-#ifndef LINK_START_LINUX_SPEC
 #define LINK_START_LINUX_SPEC "-Ttext 0x400074"
-#endif
 
-#ifndef LINK_OS_LINUX_SPEC
 #define LINK_OS_LINUX_SPEC ""
-#endif
 
-#ifndef CPP_OS_LINUX_SPEC
 #ifdef USE_GNULIBC_1
 #define CPP_OS_LINUX_SPEC "-D__unix__ -D__linux__ \
 %{!undef:%{!ansi:%{!std=*:-Dunix -Dlinux}%{std=gnu*:-Dunix -Dlinux}}} \
@@ -1360,7 +1313,6 @@ do {                                                                      \
 %{!undef:%{!ansi:%{!std=*:-Dunix -Dlinux}%{std=gnu*:-Dunix -Dlinux}}} \
 -Asystem(unix) -Asystem(posix) %{pthread:-D_REENTRANT}"
 #endif
-#endif
 
 /* Solaris support.  */
 /* For Solaris, Gcc automatically adds in one of the files
@@ -1374,7 +1326,6 @@ do {                                                                      \
    value of `_lib_version') if they will act in a strictly ANSI conforming
    manner or not.  */
 
-#ifndef        LIB_SOLARIS_SPEC
 #define LIB_SOLARIS_SPEC "\
 %{mnewlib: --start-group -lsolaris -lc --end-group } \
 %{!mnewlib: \
@@ -1385,48 +1336,83 @@ do {                                                                    \
        %{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} \
     %{solaris-cclib: /opt/SUNWspro/SC4.0/lib/libabi.a} \
     %{!shared: %{!symbolic: -lc }}}"
-#endif
 
-#ifndef        STARTFILE_SOLARIS_SPEC
 #define        STARTFILE_SOLARIS_SPEC "\
 %{!msolaris-cclib: scrti.o%s scrt0.o%s} \
 %{msolaris-cclib: /opt/SUNWspro/SC4.0/lib/crti.o%s /opt/SUNWspro/SC4.0/lib/crt1.o%s}"
-#endif
 
-#ifndef        ENDFILE_SOLARIS_SPEC
 #define        ENDFILE_SOLARIS_SPEC "\
 %{!msolaris-cclib: scrtn.o%s} \
 %{msolaris-cclib: /opt/SUNWspro/SC4.0/lib/crtn.o%s}"
-#endif
 
-#ifndef LINK_START_SOLARIS_SPEC
-#ifdef CROSS_COMPILER
+#ifdef CROSS_COMPILE
 #define LINK_START_SOLARIS_SPEC "-Ttext 0x2000074"
 #else
 #define LINK_START_SOLARIS_SPEC ""
 #endif
-#endif
 
-#ifndef LINK_OS_SOLARIS_SPEC
 #define LINK_OS_SOLARIS_SPEC ""
-#endif
 
-#ifndef CPP_OS_SOLARIS_SPEC
 #define CPP_OS_SOLARIS_SPEC "-D__ppc -D__sun__=1 -D__unix__ -D__svr4__  -D__SVR4__ \
 %{!undef:%{!ansi:%{!std=*:-Dsun=1 -Dunix -DSVR4 -D__EXTENSIONS__} \
                %{std=gnu*:-Dsun=1 -Dunix -DSVR4 -D__EXTENSIONS__}}} \
 -Amachine(prep)"
-#endif
+
+/* VxWorks support.  */
+/* VxWorks does all the library stuff itself.  */
+#define LIB_VXWORKS_SPEC ""
+
+/* VxWorks provides the functionality of crt0.o and friends itself.  */
+
+#define        STARTFILE_VXWORKS_SPEC ""
+
+#define        ENDFILE_VXWORKS_SPEC ""
+
+/* Because it uses ld -r, vxworks has no start/end files, nor starting
+   address.  */
+
+#define LINK_START_VXWORKS_SPEC ""
+
+#define LINK_OS_VXWORKS_SPEC "-r"
+
+#define CPP_OS_VXWORKS_SPEC "\
+-DCPU_FAMILY=PPC \
+%{!mcpu*: \
+  %{mpowerpc*: -DCPU=PPC603} \
+  %{!mno-powerpc: -DCPU=PPC603}} \
+%{mcpu=powerpc: -DCPU=PPC603} \
+%{mcpu=401: -DCPU=PPC403} \
+%{mcpu=403: -DCPU=PPC403} \
+%{mcpu=601: -DCPU=PPC601} \
+%{mcpu=602: -DCPU=PPC603} \
+%{mcpu=603: -DCPU=PPC603} \
+%{mcpu=603e: -DCPU=PPC603} \
+%{mcpu=ec603e: -DCPU=PPC603} \
+%{mcpu=604: -DCPU=PPC604} \
+%{mcpu=604e: -DCPU=PPC604} \
+%{mcpu=620: -DCPU=PPC604} \
+%{mcpu=740: -DCPU=PPC603} \
+%{mcpu=750: -DCPU=PPC603} \
+%{mcpu=801: -DCPU=PPC603} \
+%{mcpu=821: -DCPU=PPC603} \
+%{mcpu=823: -DCPU=PPC603} \
+%{mcpu=860: -DCPU=PPC603}"
 
 /* Define any extra SPECS that the compiler needs to generate.  */
+/* Override rs6000.h definition.  */
 #undef SUBTARGET_EXTRA_SPECS
-#define SUBTARGET_EXTRA_SPECS                                          \
+#define        SUBTARGET_EXTRA_SPECS                                           \
+  { "cpp_sysv",                        CPP_SYSV_SPEC },                        \
+  { "cpp_sysv_default",                CPP_SYSV_DEFAULT_SPEC },                \
+  { "cpp_endian_default",      CPP_ENDIAN_DEFAULT_SPEC },              \
+  { "cpp_endian",              CPP_ENDIAN_SPEC },                      \
   { "lib_ads",                 LIB_ADS_SPEC },                         \
   { "lib_yellowknife",         LIB_YELLOWKNIFE_SPEC },                 \
   { "lib_mvme",                        LIB_MVME_SPEC },                        \
   { "lib_sim",                 LIB_SIM_SPEC },                         \
   { "lib_linux",               LIB_LINUX_SPEC },                       \
   { "lib_solaris",             LIB_SOLARIS_SPEC },                     \
+  { "lib_vxworks",             LIB_VXWORKS_SPEC },                     \
   { "lib_default",             LIB_DEFAULT_SPEC },                     \
   { "startfile_ads",           STARTFILE_ADS_SPEC },                   \
   { "startfile_yellowknife",   STARTFILE_YELLOWKNIFE_SPEC },           \
@@ -1434,6 +1420,7 @@ do {                                                                      \
   { "startfile_sim",           STARTFILE_SIM_SPEC },                   \
   { "startfile_linux",         STARTFILE_LINUX_SPEC },                 \
   { "startfile_solaris",       STARTFILE_SOLARIS_SPEC },               \
+  { "startfile_vxworks",       STARTFILE_VXWORKS_SPEC },               \
   { "startfile_default",       STARTFILE_DEFAULT_SPEC },               \
   { "endfile_ads",             ENDFILE_ADS_SPEC },                     \
   { "endfile_yellowknife",     ENDFILE_YELLOWKNIFE_SPEC },             \
@@ -1441,6 +1428,7 @@ do {                                                                      \
   { "endfile_sim",             ENDFILE_SIM_SPEC },                     \
   { "endfile_linux",           ENDFILE_LINUX_SPEC },                   \
   { "endfile_solaris",         ENDFILE_SOLARIS_SPEC },                 \
+  { "endfile_vxworks",         ENDFILE_VXWORKS_SPEC },                 \
   { "endfile_default",         ENDFILE_DEFAULT_SPEC },                 \
   { "link_path",               LINK_PATH_SPEC },                       \
   { "link_shlib",              LINK_SHLIB_SPEC },                      \
@@ -1452,6 +1440,7 @@ do {                                                                      \
   { "link_start_sim",          LINK_START_SIM_SPEC },                  \
   { "link_start_linux",                LINK_START_LINUX_SPEC },                \
   { "link_start_solaris",      LINK_START_SOLARIS_SPEC },              \
+  { "link_start_vxworks",      LINK_START_VXWORKS_SPEC },              \
   { "link_start_default",      LINK_START_DEFAULT_SPEC },              \
   { "link_os",                 LINK_OS_SPEC },                         \
   { "link_os_ads",             LINK_OS_ADS_SPEC },                     \
@@ -1460,6 +1449,7 @@ do {                                                                      \
   { "link_os_sim",             LINK_OS_SIM_SPEC },                     \
   { "link_os_linux",           LINK_OS_LINUX_SPEC },                   \
   { "link_os_solaris",         LINK_OS_SOLARIS_SPEC },                 \
+  { "link_os_vxworks",         LINK_OS_VXWORKS_SPEC },                 \
   { "link_os_default",         LINK_OS_DEFAULT_SPEC },                 \
   { "cc1_endian_big",          CC1_ENDIAN_BIG_SPEC },                  \
   { "cc1_endian_little",       CC1_ENDIAN_LITTLE_SPEC },               \
@@ -1467,12 +1457,14 @@ do {                                                                    \
   { "cpp_endian_big",          CPP_ENDIAN_BIG_SPEC },                  \
   { "cpp_endian_little",       CPP_ENDIAN_LITTLE_SPEC },               \
   { "cpp_endian_solaris",      CPP_ENDIAN_SOLARIS_SPEC },              \
+  { "cpp_float_default",       CPP_FLOAT_DEFAULT_SPEC },               \
   { "cpp_os_ads",              CPP_OS_ADS_SPEC },                      \
   { "cpp_os_yellowknife",      CPP_OS_YELLOWKNIFE_SPEC },              \
   { "cpp_os_mvme",             CPP_OS_MVME_SPEC },                     \
   { "cpp_os_sim",              CPP_OS_SIM_SPEC },                      \
   { "cpp_os_linux",            CPP_OS_LINUX_SPEC },                    \
   { "cpp_os_solaris",          CPP_OS_SOLARIS_SPEC },                  \
+  { "cpp_os_vxworks",          CPP_OS_VXWORKS_SPEC },                  \
   { "cpp_os_default",          CPP_OS_DEFAULT_SPEC },
 
 /* Define this macro as a C expression for the initializer of an
@@ -1484,7 +1476,6 @@ do {                                                                      \
    the target makefile fragment or if none of the options listed in
    `MULTILIB_OPTIONS' are set by default.  *Note Target Fragment::.  */
 
-#undef MULTILIB_DEFAULTS
 #define        MULTILIB_DEFAULTS { "mbig", "mcall-sysv" }
 
 /* Define this macro if the code for function profiling should come
@@ -1493,5 +1484,4 @@ do {                                                                      \
 #define PROFILE_BEFORE_PROLOGUE 1
 
 /* Function name to call to do profiling.  */
-#undef RS6000_MCOUNT
 #define RS6000_MCOUNT "_mcount"
index 1e21acd..a19dd78 100644 (file)
@@ -1,6 +1,6 @@
 /* Target definitions for GNU compiler for a little endian PowerPC
    running System V.4
-   Copyright (C) 1995, Free Software Foundation, Inc.
+   Copyright (C) 1995, 2000 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GNU CC.
@@ -34,7 +34,9 @@ Boston, MA 02111-1307, USA.  */
 #undef LINK_TARGET_SPEC
 #define        LINK_TARGET_SPEC "\
 %{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc } \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: %{mcall-linux: -oformat elf32-powerpc}}}}}"
+%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
+    %{mcall-linux: -oformat elf32-powerpc} \
+  }}}}"
 
 /* Define this macro as a C expression for the initializer of an
    array of string to tell the driver program which options are
index 2050700..814ef42 100644 (file)
@@ -49,3 +49,11 @@ MULTILIB_MATCHES     = msoft-float=mcpu?403 \
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
 
+
+# Both 32-bit and 64-bit objects in archives
+AR_FLAGS_FOR_TARGET=-X32_64 rc
+
+# We need -lld for collect2 (actually this only matters
+# for a native compiler, but this is as good a place as any
+# to define the symbol).
+CLIB=-lld
index 408f535..231c9ce 100644 (file)
@@ -39,7 +39,7 @@ MULTILIB_MATCHES_FLOAT        = msoft-float=mcpu?401 \
                          msoft-float=mcpu?823 \
                          msoft-float=mcpu?860
 MULTILIB_MATCHES_ENDIAN        = mlittle=mlittle-endian mbig=mbig-endian
-MULTILIB_MATCHES_SYSV  = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi
+MULTILIB_MATCHES_SYSV  = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi mcall-sysv=mcall-linux
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
index 8ea37be..0765a9e 100644 (file)
@@ -3,16 +3,17 @@
 
 MULTILIB_OPTIONS       = msoft-float \
                          mlittle/mbig \
-                         mcall-sysv/mcall-aix/mcall-linux
+                         mcall-sysv/mcall-aix \
+                         fleading-underscore
 
 MULTILIB_DIRNAMES      = nof \
                          le be \
-                         cs ca lin
+                         cs ca \
+                         und
 
 MULTILIB_EXTRA_OPTS    = mrelocatable-lib mno-eabi mstrict-align
-MULTILIB_EXCEPTIONS    = *mbig/*mcall-linux* \
-                         *mlittle/*mcall-linux* \
-                         *msoft-float/*mcall-linux*
+MULTILIB_EXCEPTIONS    = *mcall-aix/*fleading-underscore* \
+                         *mlittle/*mcall-aix*
 
 MULTILIB_MATCHES       = ${MULTILIB_MATCHES_FLOAT} \
                          ${MULTILIB_MATCHES_ENDIAN} \
diff --git a/gcc/config/rs6000/t-winnt b/gcc/config/rs6000/t-winnt
deleted file mode 100644 (file)
index 1aafae4..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# Do not build libgcc1.
-LIBGCC1 = 
-CROSS_LIBGCC1 =
-
-EXTRA_PARTS = crti.o crtn.o
-
-# These are really part of libgcc1, but this will cause them to be
-# built correctly, so... [taken from t-sparclite]
-LIB2FUNCS_EXTRA = ntstack.S
-
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
-       cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
-       echo '#define FLOAT' > fp-bit.c
-       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-ntstack.S: $(srcdir)/config/rs6000/ntstack.asm
-       cat $(srcdir)/config/rs6000/ntstack.asm > ntstack.S
-
-# For NT we build crti.o and crtn.o which serve to add begin and
-# end labels for the static constructors and destructors.
-
-# Assemble startup files.
-crti.s: $(srcdir)/config/rs6000/nt-ci.asm
-       cat $(srcdir)/config/rs6000/nt-ci.asm >crti.s
-
-crtn.s: $(srcdir)/config/rs6000/nt-cn.asm
-       cat $(srcdir)/config/rs6000/nt-cn.asm >crtn.s
-
-crti.o: crti.s
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crti.o crti.s
-       
-crtn.o: crtn.s
-       $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtn.o crtn.s
index 47ab7d6..5f30489 100644 (file)
@@ -1,6 +1,6 @@
 /*  Special support for trampolines
  *
- *   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ *   Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
  *   Written By Michael Meissner
  * 
  * This file is free software; you can redistribute it and/or modify it
  *    the executable file might be covered by the GNU General Public License.
  */ 
 
-/* Set up trampolines */
+/* Set up trampolines. */
 
        .file   "tramp.asm"
        .section ".text"
        #include "ppc-asm.h"
 
-       .globl  __trampoline_initial
-       .type   __trampoline_initial,@object
+       .type   trampoline_initial,@object
        .align  2
-__trampoline_initial:
+trampoline_initial:
        mflr    r0
        bl      1f
-.Lfunc = .-__trampoline_initial
+.Lfunc = .-trampoline_initial
        .long   0                       /* will be replaced with function address */
-.Lchain = .-__trampoline_initial
+.Lchain = .-trampoline_initial
        .long   0                       /* will be replaced with static chain */
 1:     mflr    r11
        mtlr    r0
@@ -56,17 +55,9 @@ __trampoline_initial:
        mtctr   r0
        bctr
 
-__trampoline_size = .-__trampoline_initial
-       .size   __trampoline_initial,__trampoline_size
+trampoline_size = .-trampoline_initial
+       .size   trampoline_initial,trampoline_size
 
-        .section ".got2","aw"
-.LCTOC1 = .+32768
-.Ltramp = .-.LCTOC1
-        .long __trampoline_initial-4
-
-       .section ".text"
-.LCL0:
-        .long .LCTOC1-.LCF0
 
 /* R3 = stack address to store trampoline */
 /* R4 = length of trampoline area */
@@ -74,18 +65,16 @@ __trampoline_size = .-__trampoline_initial
 /* R6 = static chain */
 
 FUNC_START(__trampoline_setup)
-       mflr    r0                      /* save return address */
-        bl     .LCF0                   /* load up __trampoline_initial into r7 */
+       mflr    r0              /* save return address */
+        bl     .LCF0           /* load up __trampoline_initial into r7 */
 .LCF0:
         mflr   r11
-        lwz    r12,(.LCL0-.LCF0)(r11)
-        add    r11,r12,r11
-        lwz    r7,.Ltramp(r11)         /* trampoline address -4 */
+        addi   r7,r11,trampoline_initial-4-.LCF0 /* trampoline address -4 */
 
-       li      r8,__trampoline_size    /* verify that the trampoline is big enough */
+       li      r8,trampoline_size      /* verify that the trampoline is big enough */
        cmpw    cr1,r8,r4
-       srwi    r4,r4,2                 /* # words to move */
-       addi    r9,r3,-4                /* adjust pointer for lwzu */
+       srwi    r4,r4,2         /* # words to move */
+       addi    r9,r3,-4        /* adjust pointer for lwzu */
        mtctr   r4
        blt     cr1,.Labort
 
@@ -115,6 +104,6 @@ FUNC_START(__trampoline_setup)
        blr
 
 .Labort:
-       bl      abort
+       bl      FUNC_NAME(abort)
 FUNC_END(__trampoline_setup)
-/* END CYGNUS LOCAL -- waiting for FSF sources to be restored/meissner */
+
index 0fb8aac..fa25760 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler.  Vxworks PowerPC version.
-   Copyright (C) 1996, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1996, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -18,62 +18,41 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* This file primarily exists to give specs for the PowerPC running on
-   VxWorks.  */
+/* This file just exists to give specs for the PowerPC running on VxWorks.  */
 
 #include "rs6000/sysv4.h"
 
-/* ??? This file redefines CPP_SPEC which is wrong.  It should instead define
-   one of the extra specs that gets included in CPP_SPEC.  For instance,
-   CPP_OS_DEFAULT_SPEC.  The mrelocatable line was copied from CPP_SYSV_SPEC.
-   There is probably other stuff missing.  */
-
-#undef CPP_SPEC
-#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian) %(cpp_cpu) \
-%{mads: %(cpp_os_ads) } \
-%{myellowknife: %(cpp_os_yellowknife) } \
-%{mmvme: %(cpp_os_mvme) } \
-%{msim: %(cpp_os_sim) } \
-%{mcall-linux: %(cpp_os_linux) } \
-%{mcall-solaris: %(cpp_os_solaris) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mcall-linux: %{!mcall-solaris: %(cpp_os_default) }}}}}} \
-%{!DCPU=*: \
-  %{!mcpu*: -DCPU=PPC603} \
-  %{mcpu=powerpc: -DCPU=PPC603} \
-  %{mcpu=403: -DCPU=PPC403} \
-  %{mcpu=601: -DCPU=PPC601} \
-  %{mcpu=603: -DCPU=PPC603} \
-  %{mcpu=604: -DCPU=PPC604}}"
+/* Reset defaults */
+#undef CPP_OS_DEFAULT_SPEC
+#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)"
 
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "\
--D__vxworks -Asystem(vxworks) -Asystem(embedded) \
--Acpu(powerpc) -Amachine(powerpc)"
+#undef LIB_DEFAULT_SPEC
+#define LIB_DEFAULT_SPEC "%(lib_vxworks)"
 
-/* VxWorks does all the library stuff itself.  */
+#undef STARTFILE_DEFAULT_SPEC
+#define STARTFILE_DEFAULT_SPEC "%(startfile_vxworks)"
 
-#undef LIB_SPEC
-#define LIB_SPEC ""
+#undef ENDFILE_DEFAULT_SPEC
+#define ENDFILE_DEFAULT_SPEC "%(endfile_vxworks)"
 
-/* VxWorks uses object files, not loadable images.  make linker just
-   combine objects. */
+#undef LINK_START_DEFAULT_SPEC
+#define LINK_START_DEFAULT_SPEC "%(link_start_vxworks)"
 
-#undef LINK_SPEC
-#define LINK_SPEC "-r"
+#undef LINK_OS_DEFAULT_SPEC
+#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)"
 
-/* VxWorks provides the functionality of crt0.o and friends itself.  */
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \
+-Acpu(powerpc) -Amachine(powerpc)"
 
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC ""
+/* Don't define _LITTLE_ENDIAN or _BIG_ENDIAN */
+#undef CPP_ENDIAN_BIG_SPEC
+#define CPP_ENDIAN_BIG_SPEC "-D__BIG_ENDIAN__ -Amachine(bigendian)"
 
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC ""
+#undef CPP_ENDIAN_LITTLE_SPEC
+#define CPP_ENDIAN_LITTLE_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)"
 
 /* We use stabs-in-elf for debugging */
 #undef PREFERRED_DEBUGGING_TYPE
 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-/* VxWorks normally doesn't have an unaligned handler, so make -mstrict-align
-   the default.  */
-#undef SUBTARGET_DEFAULT
-#define SUBTARGET_DEFAULT MASK_STRICT_ALIGN
diff --git a/gcc/config/rs6000/vxppcle.h b/gcc/config/rs6000/vxppcle.h
new file mode 100644 (file)
index 0000000..fadec99
--- /dev/null
@@ -0,0 +1,58 @@
+/* Definitions of target machine for GNU compiler.  Vxworks PowerPC version.
+   Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* This file just exists to give specs for the PowerPC running on VxWorks.  */
+
+#include "rs6000/sysv4le.h"
+
+/* Reset defaults */
+#undef CPP_OS_DEFAULT_SPEC
+#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)"
+
+#undef LIB_DEFAULT_SPEC
+#define LIB_DEFAULT_SPEC "%(lib_vxworks)"
+
+#undef STARTFILE_DEFAULT_SPEC
+#define STARTFILE_DEFAULT_SPEC "%(startfile_vxworks)"
+
+#undef ENDFILE_DEFAULT_SPEC
+#define ENDFILE_DEFAULT_SPEC "%(endfile_vxworks)"
+
+#undef LINK_START_DEFAULT_SPEC
+#define LINK_START_DEFAULT_SPEC "%(link_start_vxworks)"
+
+#undef LINK_OS_DEFAULT_SPEC
+#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)"
+
+#undef CPP_PREDEFINES
+#define CPP_PREDEFINES "\
+-D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \
+-Acpu(powerpc) -Amachine(powerpc)"
+
+/* Don't define _LITTLE_ENDIAN or _BIG_ENDIAN */
+#undef CPP_ENDIAN_BIG_SPEC
+#define CPP_ENDIAN_BIG_SPEC "-D__BIG_ENDIAN__ -Amachine(bigendian)"
+
+#undef CPP_ENDIAN_LITTLE_SPEC
+#define CPP_ENDIAN_LITTLE_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)"
+
+/* We use stabs-in-elf for debugging */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/rs6000/win-nt.h b/gcc/config/rs6000/win-nt.h
deleted file mode 100644 (file)
index 796e487..0000000
+++ /dev/null
@@ -1,483 +0,0 @@
-/* Definitions of target machine for GNU compiler, for PowerPC
-   running Windows/NT.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
-   Contributed by Cygnus Support.
-
-This file is part of GNU CC.
-
-GNU CC 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.
-
-GNU CC 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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-/* Say this is Windows/NT for the other config files.  */
-#define WINDOWS_NT 1
-#define COFF_WITH_PE 1
-
-/* Default ABI to compile code for */
-#define DEFAULT_ABI ABI_NT
-
-#define CPP_DEFAULT_SPEC "-D_ARCH_PPC"
-
-#define ASM_DEFAULT_SPEC "-mppc"
-
-/* Pseudo target that we can test in the md file.  */
-#define        TARGET_WINDOWS_NT 1
-
-#include "rs6000/rs6000.h"
-
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS)
-
-#undef PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_POWERPC
-
-#undef CPP_PREDEFINES
-#define        CPP_PREDEFINES "-DWIN32 -D_WIN32 \
-  -DWINNT -D__STDC__=0 -DALMOST_STDC \
-  -D_POWER -D_ARCH_PPC -D__PPC__ -Asystem(winnt) -Acpu(powerpc) -Amachine(powerpc)"
-
-#if 0
-#include "winnt/win-nt.h"
-#endif
-
-#undef LIB_SPEC
-#define        LIB_SPEC "%{mwindows:-subsystem:windows -entry:WinMainCRTStartup \
-  USER32.LIB GDI32.LIB COMDLG32.LIB WINSPOOL.LIB} \
- %{!mwindows:-subsystem console -e mainCRTStartup} \
- %{mcrtmt:LIBCMT.LIB KERNEL32.LIB} %{!mcrtmt:-lkernel32 -lcygwin} \
- %{v}"
-
-#undef LINK_SPEC
-#define        LINK_SPEC "%{v:-V}"
-
-/* Allow switches specified in LIB_SPEC, but don't do anything with them
-   in the compiler.  */
-#undef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES     \
-   { "windows",        0 },            \
-   { "crtmt",  0 },
-
-#undef XCOFF_DEBUGGING_INFO
-
-/* this is pure coff, not xcoff */
-#define SDB_DEBUGGING_INFO
-#define DBX_DEBUGGING_INFO
-
-#undef  SDB_DELIM
-#define SDB_DELIM ";"
-
-#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-/* NT always runs little endian */
-#undef  BYTES_BIG_ENDIAN
-#define BYTES_BIG_ENDIAN 0 
-
-#undef  WORDS_BIG_ENDIAN
-#define WORDS_BIG_ENDIAN 0 
-
-/* Define cutoff for using external functions to save floating point.
-   Currently on NT, always use inline stores */
-#undef FP_SAVE_INLINE
-#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
-
-/* Note, little endian systems trap on unaligned addresses, so never
-   turn off strict alignment in that case. */
-
-#undef STRICT_ALIGNMENT
-#define        STRICT_ALIGNMENT 1
-
-/* Align stack to 16 byte boundaries */
-#undef STACK_BOUNDARY
-#define        STACK_BOUNDARY  128
-
-/* No data type wants to be aligned rounder than this.  */
-#undef BIGGEST_ALIGNMENT
-#define BIGGEST_ALIGNMENT 128
-
-/* NT aligns internal doubles in structures on dword boundaries.  */
-#undef BIGGEST_FIELD_ALIGNMENT
-#define BIGGEST_FIELD_ALIGNMENT 64
-
-#undef  ADJUST_FIELD_ALIGN
-#undef  ROUND_TYPE_ALIGN
-
-#undef TARGET_VERSION
-#define TARGET_VERSION fprintf (stderr, " (PowerPC PE)");
-
-#undef TARGET_DEFAULT 
-#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC)
-
-/* MEM representing address to save the TOC register */
-#undef RS6000_SAVE_TOC
-#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \
-                                    plus_constant (virtual_incoming_args_rtx,
-                                                   -RS6000_SAVE_AREA - 8))
-
-/* Windows NT specifies that r13 is reserved to the OS, so it is not available
-   to the normal user.  */
-
-#undef FIXED_R13
-#define FIXED_R13 1
-\f
-/* This says how to output an assembler line
-   to define a global common symbol.  */
-
-#undef ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNMENT) \
-  do { fputs ("\t.comm \t", (FILE));                           \
-       assemble_name ((FILE), (NAME));                         \
-       if ( (SIZE) > 4)                                         \
-         fprintf ((FILE), ",%d,%d\n", (SIZE), 3);               \
-       else                                                     \
-        fprintf( (FILE), ",%d\n", (SIZE));                     \
-  } while (0) 
-
-#undef ASM_OUTPUT_ALIGNED_LOCAL
-
-/* This says how to output an assembler line
-   to define a global common symbol.  */
-
-#undef  ASM_OUTPUT_COMMON
-#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)   \
-  do { fputs ("\t.comm \t", (FILE));                   \
-       assemble_name ((FILE), (NAME));                 \
-       fprintf ((FILE), ",%d\n", (SIZE)); } while (0)
-
-/* This says how to output an assembler line
-   to define an aligned local common symbol.  */
-
-#undef ASM_OUTPUT_ALIGNED_LOCAL
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)              \
-do {                                                                   \
-  bss_section ();                                                      \
-  ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT));         \
-  ASM_OUTPUT_LABEL (FILE, NAME);                                       \
-  ASM_OUTPUT_SKIP (FILE, SIZE);                                                \
-} while (0)
-
-/* Describe how to emit uninitialized external linkage items  */
-#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)          \
-do {                                                                   \
-  ASM_GLOBALIZE_LABEL (FILE, NAME);                                    \
-  ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN);                  \
-} while (0)
-
-/* 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))
-
-
-/* Stuff to force fit us into the Motorola PPC assembler */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE)                                           \
-do {                                                                   \
-  output_file_directive ((FILE), main_input_filename);                 \
-  rs6000_file_start (FILE, TARGET_CPU_DEFAULT);                                \
-  data_section ();                                                     \
-} while (0)
-
-#undef ASM_FILE_END
-
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL)                      \
-{                                                                      \
-  tree exception_args;                                                 \
-  int i;                                                               \
-                                                                       \
-  if (TREE_PUBLIC (DECL))                                              \
-    {                                                                  \
-      fprintf (FILE, "\t.globl ..");                                   \
-      assemble_name (FILE, NAME);                                      \
-      fprintf (FILE, "\n");                                            \
-    }                                                                  \
-                                                                       \
-  fprintf (FILE, "\n#\tFunction: '..");                                        \
-  assemble_name (FILE, NAME);                                          \
-  fputs ("'\n", FILE);                                                 \
-  fputs ("#\tText in section: <default>\n\n", FILE);                   \
-  fputs ("#\tSetup MS Structured-Exception-Handling\n", FILE);         \
-  fputs ("\t.pdata\n", FILE);                                          \
-  fputs ("\t.align 2\n", FILE);                                                \
-  fputs ("\t.ualong ..", FILE);                                                \
-  assemble_name (FILE, NAME);                                          \
-  fputs (",", FILE);                                                   \
-  assemble_name (FILE, NAME);                                          \
-  fputs (".e,", FILE);                                                 \
-  exception_args = lookup_attribute ("exception",                      \
-                                    TYPE_ATTRIBUTES (TREE_TYPE (DECL))); \
-                                                                       \
-  if (exception_args)                                                  \
-    exception_args = TREE_VALUE (exception_args);                      \
-                                                                       \
-  for (i = 0; i < 2; i++)                                              \
-    {                                                                  \
-      if (!exception_args)                                             \
-       fputs ("0,", FILE);                                             \
-      else                                                             \
-       {                                                               \
-         tree field = TREE_VALUE (exception_args);                     \
-         exception_args = TREE_PURPOSE (exception_args);               \
-         if (TREE_CODE (field) == STRING_CST)                          \
-           fprintf (FILE, "%.*s,", TREE_STRING_LENGTH (field),         \
-                    TREE_STRING_POINTER (field));                      \
-         else if (TREE_CODE (field) == IDENTIFIER_NODE)                \
-           fprintf (FILE, "%.*s,", IDENTIFIER_LENGTH (field),          \
-                    IDENTIFIER_POINTER (field));                       \
-         else                                                          \
-           abort ();                                                   \
-       }                                                               \
-    }                                                                  \
-                                                                       \
-  assemble_name (FILE, NAME);                                          \
-  fprintf (FILE, ".b\n\n");                                            \
-  fprintf (FILE, "#\tSwitch to the relocation section\n");             \
-  fprintf (FILE, "\t.reldata\n");                                      \
-  assemble_name (FILE, NAME);                                          \
-  fprintf (FILE, ":\n");                                               \
-  fprintf (FILE, "\t.ualong ..");                                      \
-  assemble_name (FILE, NAME);                                          \
-  fprintf (FILE, ",.toc\n");                                           \
-                                                                       \
-  if (lookup_attribute ("dllexport",                                   \
-                       TYPE_ATTRIBUTES (TREE_TYPE (DECL))))            \
-    {                                                                  \
-      fprintf (FILE, "\t.globl __imp_");                               \
-      assemble_name (FILE, NAME);                                      \
-      fprintf (FILE, "\n__imp_");                                      \
-      assemble_name (FILE, NAME);                                      \
-      fprintf (FILE, ":\n\t.ulong ");                                  \
-      assemble_name (FILE, NAME);                                      \
-      fprintf (FILE, "\n");                                            \
-    }                                                                  \
-                                                                       \
-  fprintf (FILE, "\t.section .text\n\t.align 2\n..");                  \
-  assemble_name (FILE, NAME);                                          \
-  fprintf (FILE, ":\n");                                               \
-  fprintf (FILE, "\t.function\t..");                                   \
-  assemble_name (FILE, NAME);                                          \
-  fprintf (FILE, "\n");                                                        \
-}
-
-/* This is how to output an assembler line defining a `double' constant.  */
-
-#undef ASM_OUTPUT_DOUBLE
-#define ASM_OUTPUT_DOUBLE(FILE, VALUE)                                 \
-  {                                                                    \
-    if (REAL_VALUE_ISINF (VALUE)                                       \
-        || REAL_VALUE_ISNAN (VALUE)                                    \
-       || REAL_VALUE_MINUS_ZERO (VALUE))                               \
-      {                                                                        \
-       long t[2];                                                      \
-       REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);                       \
-       fprintf (FILE, "\t.ualong 0x%lx\n\t.long 0x%lx\n",              \
-               t[0] & 0xffffffff, t[1] & 0xffffffff);                  \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       char str[30];                                                   \
-       REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str);                    \
-       fprintf (FILE, "\t.double %s\n", str);                          \
-      }                                                                        \
-  }
-
-/* This is how to output an assembler line defining a `float' constant.  */
-
-#undef ASM_OUTPUT_FLOAT
-#define ASM_OUTPUT_FLOAT(FILE, VALUE)                                  \
-  {                                                                    \
-    if (REAL_VALUE_ISINF (VALUE)                                       \
-        || REAL_VALUE_ISNAN (VALUE)                                    \
-       || REAL_VALUE_MINUS_ZERO (VALUE))                               \
-      {                                                                        \
-       long t;                                                         \
-       REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);                       \
-       fprintf (FILE, "\t.ualong 0x%lx\n", t & 0xffffffff);            \
-      }                                                                        \
-    else                                                               \
-      {                                                                        \
-       char str[30];                                                   \
-       REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str);                  \
-       fprintf (FILE, "\t.float %s\n", str);                           \
-      }                                                                        \
-  }
-
-/* Output before instructions.  */
-#undef TEXT_SECTION_ASM_OP
-#define TEXT_SECTION_ASM_OP "\t.text"
-
-/* Output before writable data.  */
-#undef DATA_SECTION_ASM_OP
-#define DATA_SECTION_ASM_OP "\t.data"
-
-/* Output to the bss section.  */
-#undef BSS_SECTION_ASM_OP
-#define BSS_SECTION_ASM_OP "\t.section .bss"
-
-/* Define the extra sections we need.  We define a dummy TOC section,
-   plus sections to hold the list of static constructors (.ctors) and
-   destructors (.dtors).  */
-
-#undef READONLY_DATA_SECTION
-#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_toc, in_ctors, in_dtors
-
-/* Define the routines to implement these extra sections.  */
-
-#undef EXTRA_SECTION_FUNCTIONS
-#define EXTRA_SECTION_FUNCTIONS                                                \
-  CTORS_SECTION_FUNCTION                                               \
-  DTORS_SECTION_FUNCTION                                               \
-  TOC_SECTION_FUNCTION                                                 \
-
-#define TOC_SECTION_FUNCTION                                           \
-void                                                                   \
-toc_section ()                                                         \
-{                                                                      \
-}
-
-#define CTORS_SECTION_ASM_OP   ".section\t.ctors"
-#define CTORS_SECTION_FUNCTION                                         \
-void                                                                   \
-ctors_section ()                                                       \
-{                                                                      \
-  if (in_section != in_ctors)                                          \
-    {                                                                  \
-      fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP);            \
-      in_section = in_ctors;                                           \
-    }                                                                  \
-}
-
-#define DTORS_SECTION_ASM_OP   ".section\t.dtors"
-#define DTORS_SECTION_FUNCTION                                         \
-void                                                                   \
-dtors_section ()                                                       \
-{                                                                      \
-  if (in_section != in_dtors)                                          \
-    {                                                                  \
-      fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP);            \
-      in_section = in_dtors;                                           \
-    }                                                                  \
-}
-
-#undef SELECT_SECTION
-#undef SELECT_RTX_SECTION
-
-/* Make sure __main gets called */
-#define INVOKE__main 1
-
-/* A C statement (sans semicolon) to output an element in the table of
-   global constructors.  */
-#undef ASM_OUTPUT_CONSTRUCTOR
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME)                              \
-  do {                                                                 \
-    ctors_section ();                                                  \
-    fprintf (FILE, "\t.ualong ");                                      \
-    assemble_name (FILE, NAME);                                                \
-    fprintf (FILE, "\n");                                              \
-  } while (0)
-
-/* A C statement (sans semicolon) to output an element in the table of
-   global destructors.  */
-#undef ASM_OUTPUT_DESTRUCTOR
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME)                                       \
-  do {                                                                 \
-    dtors_section ();                                                  \
-    fprintf (FILE, "\t.ualong ");                                      \
-    assemble_name (FILE, NAME);                                        \
-    fprintf (FILE, "\n");                                              \
-  } while (0)
-
-
-/* Text to write out after a CALL that may be replaced by glue code by
-   the loader.  The motorola asm demands that, for dll support, a .znop
-   be issued after a bl instruction, and the symbol on the .znop is the
-   symbol on the bl instruction */
-
-#undef RS6000_CALL_GLUE
-#define RS6000_CALL_GLUE "nop #\tFIXME: only works for non-dll calls."
-
-#define RS6000_CALL_GLUE2 ".znop "
-
-#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY
-
-/* Output something to declare an external symbol to the assembler.  Most
-   assemblers don't need this.  */
-
-#undef ASM_OUTPUT_EXTERNAL
-
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)                          \
-{                                                                      \
-  char *_name;                                                         \
-  rtx _symref = XEXP (DECL_RTL (DECL), 0);                             \
-  if ((TREE_CODE (DECL) == VAR_DECL                                    \
-       || TREE_CODE (DECL) == FUNCTION_DECL)                           \
-      && (NAME)[strlen (NAME) - 1] != ']')                             \
-    {                                                                  \
-      _name = (char *) permalloc (strlen (XSTR (_symref, 0)) + 5);     \
-      strcpy (_name, XSTR (_symref, 0));                               \
-      XSTR (_symref, 0) = _name;                                       \
-    }                                                                  \
-  else                                                                 \
-    _name = XSTR (_symref, 0);                                         \
-                                                                       \
-  if (DECL_FUNCTION_CODE (DECL) == 0)                                  \
-    {                                                                  \
-      fputs ("\t.extern ", FILE);                                      \
-      assemble_name (FILE, _name);                                     \
-      putc ('\n', FILE);                                               \
-      if (TREE_CODE (DECL) == FUNCTION_DECL)                           \
-       {                                                               \
-         fputs ("\t.extern ..", FILE);                                 \
-         assemble_name (FILE, _name);                                  \
-         putc ('\n', FILE);                                            \
-       }                                                               \
-    }                                                                  \
-}
-
-/* Similar, but for libcall.  We only have to worry about the function name,
-   not that of the descriptor. */
-
-#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
-{ fprintf (FILE, "\t.extern ..");              \
-  assemble_name (FILE, XSTR (FUN, 0));         \
-  fprintf (FILE, "\n");                                \
-}
-
-/* The prefix to add to user-visible assembler symbols. */
-
-#define USER_LABEL_PREFIX ".."
-
-/* Eliminate AIX style constant pool processing */
-#undef LEGITIMATE_CONSTANT_POOL_BASE_P
-#define        LEGITIMATE_CONSTANT_POOL_BASE_P(X) 0
-
-#undef LEGITIMATE_CONSTANT_POOL_ADDRESS_P
-#define        LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) 0
-
-#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY
-
-#undef  ASM_IDENTIFY_GCC
-#define ASM_IDENTIFY_GCC(x)
-
-/* Output assembler code for a block containing the constant parts
-   of a trampoline, leaving space for the variable parts.
-
-   The trampoline should set the static chain pointer to value placed
-   into the trampoline and should branch to the specified routine.  */
-#define TRAMPOLINE_TEMPLATE(FILE) rs6000_trampoline_template (FILE)
index 69c666b..f978be1 100644 (file)
@@ -2,11 +2,3 @@
 
 # Show we need to use the C version of ALLOCA
 ALLOCA=alloca.o
-
-# We need -lld for collect2 (actually this only matters
-# for a native compiler, but this is as good a place as any
-# to define the symbol).
-CLIB=-lld
-
-# f771 and cc1plus overflow the AIX TOC
-BOOT_LDFLAGS=-Wl,-bbigtoc
diff --git a/gcc/config/rs6000/x-aix41-gld b/gcc/config/rs6000/x-aix41-gld
deleted file mode 100644 (file)
index ca444ae..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# configuration for IBM RS/6000 running AIX 4.1+
-
-# Show we need to use the C version of ALLOCA
-ALLOCA=alloca.o
-
-# We need -lld for collect2 (actually this only matters
-# for a native compiler, but this is as good a place as any
-# to define the symbol).
-CLIB=-lld
-
-# f771 and cc1plus overflow the AIX TOC, however gld doesn't support -bbigtoc
-# BOOT_LDFLAGS=-Wl,-bbigtoc
diff --git a/gcc/config/rs6000/x-aix43 b/gcc/config/rs6000/x-aix43
deleted file mode 100644 (file)
index 072d925..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# configuration for IBM RS/6000 running AIX 4.3+
-
-# Show we need to use the C version of ALLOCA
-ALLOCA=alloca.o
-
-# We need -lld for collect2 (actually this only matters
-# for a native compiler, but this is as good a place as any
-# to define the symbol).
-CLIB=-lld
-
-# f771 and cc1plus overflow the AIX TOC
-BOOT_LDFLAGS=-Wl,-bbigtoc
-
-# Both 32-bit and 64-bit objects in archives
-AR_FOR_TARGET=ar -X32_64
index 4fdd12f..432f120 100755 (executable)
@@ -1369,7 +1369,7 @@ else
 fi
 
 # Find some useful tools
-for ac_prog in mawk gawk nawk awk
+for ac_prog in gawk mawk nawk awk
 do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
@@ -5694,6 +5694,15 @@ for machine in $build $host $target; do
                extra_headers=ppc-asm.h
                thread_file='vxworks'
                 ;;
+        powerpcle-wrs-vxworks*)
+                cpu_type=rs6000
+               xm_file="rs6000/xm-sysv4.h"
+               xm_defines="USG POSIX"
+                tm_file=rs6000/vxppcle.h
+                tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+               extra_headers=ppc-asm.h
+               thread_file='vxworks'
+                ;;
        powerpcle-*-sysv* | powerpcle-*-elf*)
                tm_file=rs6000/sysv4le.h
                xm_file="rs6000/xm-sysv4.h"
@@ -5722,27 +5731,6 @@ for machine in $build $host $target; do
                fi
                extra_headers=ppc-asm.h
                ;;
-        powerpcle-*-winnt* )
-                tm_file=rs6000/win-nt.h
-                tmake_file=rs6000/t-winnt
-#               extra_objs=pe.o
-               if test x$enable_threads = xyes; then
-                       thread_file='win32'
-               fi
-               extra_headers=ppc-asm.h
-               ;;
-       powerpcle-*-pe | powerpcle-*-cygwin*)
-               tm_file=rs6000/cygwin.h
-               xm_file="rs6000/xm-cygwin.h ${xm_file}"
-               tmake_file=rs6000/t-winnt
-               xmake_file=rs6000/x-cygwin
-#              extra_objs=pe.o
-               if test x$enable_threads = xyes; then
-                       thread_file='win32'
-               fi
-               exeext=.exe
-               extra_headers=ppc-asm.h
-               ;;
        powerpcle-*-solaris2*)
                tm_file=rs6000/sol2.h
                xm_file="rs6000/xm-sysv4.h"
@@ -5781,36 +5769,21 @@ for machine in $build $host $target; do
                else
                        tmake_file=rs6000/t-newas
                fi
-               if test "$gnu_ld" = yes
-               then
-                       xmake_file=rs6000/x-aix41-gld
-               else
-                       xmake_file=rs6000/x-aix41
-               fi
+               xmake_file=rs6000/x-aix41
                float_format=none
                use_collect2=yes
                ;;
        rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
                tm_file=rs6000/aix43.h
-               if test x$host != x$target
-               then
-                       tmake_file=rs6000/t-xaix43
-               else
-                       tmake_file=rs6000/t-aix43
-               fi
-               xmake_file=rs6000/x-aix43
+               tmake_file=rs6000/t-aix43
+               xmake_file=rs6000/x-aix41
                float_format=none
                use_collect2=yes
                ;;
        rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
                tm_file=rs6000/aix43.h
-               if test x$host != x$target
-               then
-                       tmake_file=rs6000/t-xaix43
-               else
-                       tmake_file=rs6000/t-aix43
-               fi
-               xmake_file=rs6000/x-aix43
+               tmake_file=rs6000/t-aix43
+               xmake_file=rs6000/x-aix41
                float_format=none
                use_collect2=yes
                ;;
@@ -6678,7 +6651,7 @@ fi
 
 
         echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
-echo "configure:6682: checking for strerror in -lcposix" >&5
+echo "configure:6655: checking for strerror in -lcposix" >&5
 ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6686,7 +6659,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lcposix  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6690 "configure"
+#line 6663 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6697,7 +6670,7 @@ int main() {
 strerror()
 ; return 0; }
 EOF
-if { (eval echo configure:6701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6720,12 +6693,12 @@ fi
   
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:6724: checking for working const" >&5
+echo "configure:6697: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6729 "configure"
+#line 6702 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -6774,7 +6747,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:6778: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -6795,21 +6768,21 @@ EOF
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:6799: checking for inline" >&5
+echo "configure:6772: checking for inline" >&5
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 6806 "configure"
+#line 6779 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:6813: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -6835,12 +6808,12 @@ EOF
 esac
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:6839: checking for off_t" >&5
+echo "configure:6812: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6844 "configure"
+#line 6817 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6868,12 +6841,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:6872: checking for size_t" >&5
+echo "configure:6845: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6877 "configure"
+#line 6850 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6903,19 +6876,19 @@ fi
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:6907: checking for working alloca.h" >&5
+echo "configure:6880: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6912 "configure"
+#line 6885 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:6919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -6936,12 +6909,12 @@ EOF
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:6940: checking for alloca" >&5
+echo "configure:6913: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6945 "configure"
+#line 6918 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -6969,7 +6942,7 @@ int main() {
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:6973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -7001,12 +6974,12 @@ EOF
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:7005: checking whether alloca needs Cray hooks" >&5
+echo "configure:6978: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7010 "configure"
+#line 6983 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -7031,12 +7004,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7035: checking for $ac_func" >&5
+echo "configure:7008: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7040 "configure"
+#line 7013 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7059,7 +7032,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7063: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7086,7 +7059,7 @@ done
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:7090: checking stack direction for C alloca" >&5
+echo "configure:7063: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7094,7 +7067,7 @@ else
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 7098 "configure"
+#line 7071 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -7113,7 +7086,7 @@ main ()
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:7117: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -7138,17 +7111,17 @@ for ac_hdr in unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7142: checking for $ac_hdr" >&5
+echo "configure:7115: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7147 "configure"
+#line 7120 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7125: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -7177,12 +7150,12 @@ done
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7181: checking for $ac_func" >&5
+echo "configure:7154: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7186 "configure"
+#line 7159 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7205,7 +7178,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7209: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7230,7 +7203,7 @@ fi
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:7234: checking for working mmap" >&5
+echo "configure:7207: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7238,7 +7211,7 @@ else
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 7242 "configure"
+#line 7215 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -7378,7 +7351,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:7382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -7406,17 +7379,17 @@ unistd.h sys/param.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7410: checking for $ac_hdr" >&5
+echo "configure:7383: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7415 "configure"
+#line 7388 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -7446,12 +7419,12 @@ done
 strdup __argz_count __argz_stringify __argz_next
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7450: checking for $ac_func" >&5
+echo "configure:7423: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7455 "configure"
+#line 7428 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7474,7 +7447,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7478: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7503,12 +7476,12 @@ done
      for ac_func in stpcpy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7507: checking for $ac_func" >&5
+echo "configure:7480: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7512 "configure"
+#line 7485 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7531,7 +7504,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7565,19 +7538,19 @@ EOF
 
    if test $ac_cv_header_locale_h = yes; then
     echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:7569: checking for LC_MESSAGES" >&5
+echo "configure:7542: checking for LC_MESSAGES" >&5
 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7574 "configure"
+#line 7547 "configure"
 #include "confdefs.h"
 #include <locale.h>
 int main() {
 return LC_MESSAGES
 ; return 0; }
 EOF
-if { (eval echo configure:7581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   am_cv_val_LC_MESSAGES=yes
 else
@@ -7598,7 +7571,7 @@ EOF
     fi
   fi
    echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:7602: checking whether NLS is requested" >&5
+echo "configure:7575: checking whether NLS is requested" >&5
         # Check whether --enable-nls or --disable-nls was given.
 if test "${enable_nls+set}" = set; then
   enableval="$enable_nls"
@@ -7618,7 +7591,7 @@ fi
 EOF
 
       echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:7622: checking whether included gettext is requested" >&5
+echo "configure:7595: checking whether included gettext is requested" >&5
       # Check whether --with-included-gettext or --without-included-gettext was given.
 if test "${with_included_gettext+set}" = set; then
   withval="$with_included_gettext"
@@ -7637,17 +7610,17 @@ fi
 
        ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:7641: checking for libintl.h" >&5
+echo "configure:7614: checking for libintl.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7646 "configure"
+#line 7619 "configure"
 #include "confdefs.h"
 #include <libintl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7651: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7624: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -7664,19 +7637,19 @@ fi
 if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
-echo "configure:7668: checking for gettext in libc" >&5
+echo "configure:7641: checking for gettext in libc" >&5
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7673 "configure"
+#line 7646 "configure"
 #include "confdefs.h"
 #include <libintl.h>
 int main() {
 return (int) gettext ("")
 ; return 0; }
 EOF
-if { (eval echo configure:7680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   gt_cv_func_gettext_libc=yes
 else
@@ -7692,7 +7665,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
 
           if test "$gt_cv_func_gettext_libc" != "yes"; then
             echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
-echo "configure:7696: checking for bindtextdomain in -lintl" >&5
+echo "configure:7669: checking for bindtextdomain in -lintl" >&5
 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7700,7 +7673,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7704 "configure"
+#line 7677 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7711,7 +7684,7 @@ int main() {
 bindtextdomain()
 ; return 0; }
 EOF
-if { (eval echo configure:7715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7727,12 +7700,12 @@ fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
-echo "configure:7731: checking for gettext in libintl" >&5
+echo "configure:7704: checking for gettext in libintl" >&5
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
-echo "configure:7736: checking for gettext in -lintl" >&5
+echo "configure:7709: checking for gettext in -lintl" >&5
 ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7740,7 +7713,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7744 "configure"
+#line 7717 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7751,7 +7724,7 @@ int main() {
 gettext()
 ; return 0; }
 EOF
-if { (eval echo configure:7755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7790,7 +7763,7 @@ EOF
              # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7794: checking for $ac_word" >&5
+echo "configure:7767: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7824,12 +7797,12 @@ fi
                for ac_func in dcgettext
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7828: checking for $ac_func" >&5
+echo "configure:7801: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7833 "configure"
+#line 7806 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7852,7 +7825,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:7856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7879,7 +7852,7 @@ done
                # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7883: checking for $ac_word" >&5
+echo "configure:7856: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7915,7 +7888,7 @@ fi
                # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7919: checking for $ac_word" >&5
+echo "configure:7892: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7947,7 +7920,7 @@ else
 fi
 
                cat > conftest.$ac_ext <<EOF
-#line 7951 "configure"
+#line 7924 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -7955,7 +7928,7 @@ extern int _nl_msg_cat_cntr;
                               return _nl_msg_cat_cntr
 ; return 0; }
 EOF
-if { (eval echo configure:7959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   CATOBJEXT=.gmo
                   DATADIRNAME=share
@@ -7978,7 +7951,7 @@ fi
 
         if test "$CATOBJEXT" = "NONE"; then
          echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
-echo "configure:7982: checking whether catgets can be used" >&5
+echo "configure:7955: checking whether catgets can be used" >&5
          # Check whether --with-catgets or --without-catgets was given.
 if test "${with_catgets+set}" = set; then
   withval="$with_catgets"
@@ -7991,7 +7964,7 @@ fi
 
          if test "$nls_cv_use_catgets" = "yes"; then
                    echo $ac_n "checking for main in -li""... $ac_c" 1>&6
-echo "configure:7995: checking for main in -li" >&5
+echo "configure:7968: checking for main in -li" >&5
 ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7999,14 +7972,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-li  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8003 "configure"
+#line 7976 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:8010: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8034,12 +8007,12 @@ else
 fi
 
            echo $ac_n "checking for catgets""... $ac_c" 1>&6
-echo "configure:8038: checking for catgets" >&5
+echo "configure:8011: checking for catgets" >&5
 if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8043 "configure"
+#line 8016 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char catgets(); below.  */
@@ -8062,7 +8035,7 @@ catgets();
 
 ; return 0; }
 EOF
-if { (eval echo configure:8066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_catgets=yes"
 else
@@ -8084,7 +8057,7 @@ EOF
               # Extract the first word of "gencat", so it can be a program name with args.
 set dummy gencat; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8088: checking for $ac_word" >&5
+echo "configure:8061: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8120,7 +8093,7 @@ fi
                 # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8124: checking for $ac_word" >&5
+echo "configure:8097: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8157,7 +8130,7 @@ fi
                   # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8161: checking for $ac_word" >&5
+echo "configure:8134: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8192,7 +8165,7 @@ fi
                 # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8196: checking for $ac_word" >&5
+echo "configure:8169: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8250,7 +8223,7 @@ fi
         # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8254: checking for $ac_word" >&5
+echo "configure:8227: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8284,7 +8257,7 @@ fi
         # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8288: checking for $ac_word" >&5
+echo "configure:8261: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8320,7 +8293,7 @@ fi
         # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8324: checking for $ac_word" >&5
+echo "configure:8297: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8413,7 +8386,7 @@ fi
        LINGUAS=
      else
        echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:8417: checking for catalogs to be installed" >&5
+echo "configure:8390: checking for catalogs to be installed" >&5
        NEW_LINGUAS=
        for lang in ${LINGUAS=$ALL_LINGUAS}; do
          case "$ALL_LINGUAS" in
@@ -8441,17 +8414,17 @@ echo "configure:8417: checking for catalogs to be installed" >&5
    if test "$CATOBJEXT" = ".cat"; then
      ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
-echo "configure:8445: checking for linux/version.h" >&5
+echo "configure:8418: checking for linux/version.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8450 "configure"
+#line 8423 "configure"
 #include "confdefs.h"
 #include <linux/version.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8455: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8428: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -8526,7 +8499,7 @@ fi
 
 
 echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6
-echo "configure:8530: checking whether windows registry support is requested" >&5
+echo "configure:8503: checking whether windows registry support is requested" >&5
 if test x$enable_win32_registry != xno; then
   cat >> confdefs.h <<\EOF
 #define ENABLE_WIN32_REGISTRY 1
@@ -8555,7 +8528,7 @@ esac
 
 if test x$enable_win32_registry != xno; then
   echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6
-echo "configure:8559: checking registry key on windows hosts" >&5
+echo "configure:8532: checking registry key on windows hosts" >&5
   cat >> confdefs.h <<EOF
 #define WIN32_REGISTRY_KEY "$gcc_cv_win32_registry_key"
 EOF
@@ -8731,7 +8704,7 @@ fi
 
 # Figure out what assembler alignment features are present.
 echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:8735: checking assembler alignment features" >&5
+echo "configure:8708: checking assembler alignment features" >&5
 gcc_cv_as=
 gcc_cv_as_alignment_features=
 gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
@@ -8852,7 +8825,7 @@ fi
 echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
 
 echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:8856: checking assembler subsection support" >&5
+echo "configure:8829: checking assembler subsection support" >&5
 gcc_cv_as_subsections=
 if test x$gcc_cv_as != x; then
        # Check if we have .subsection
@@ -8892,7 +8865,7 @@ fi
 echo "$ac_t""$gcc_cv_as_subsections" 1>&6
 
 echo $ac_n "checking assembler weak support""... $ac_c" 1>&6
-echo "configure:8896: checking assembler weak support" >&5
+echo "configure:8869: checking assembler weak support" >&5
 gcc_cv_as_weak=
 if test x$gcc_cv_as != x; then
        # Check if we have .weak
@@ -8911,7 +8884,7 @@ echo "$ac_t""$gcc_cv_as_weak" 1>&6
 case "$target" in 
   sparc*-*-*)
     echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:8915: checking assembler .register pseudo-op support" >&5
+echo "configure:8888: checking assembler .register pseudo-op support" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8941,7 +8914,7 @@ EOF
     case "$tm_file" in
     *64*)
        echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
-echo "configure:8945: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
+echo "configure:8918: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8986,7 +8959,7 @@ EOF
 
     if test "x$gcc_cv_as_flags64" != xno; then
        echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:8990: checking for assembler offsetable %lo() support" >&5
+echo "configure:8963: checking for assembler offsetable %lo() support" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -9025,7 +8998,7 @@ EOF
 
   i[34567]86-*-*)
     echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:9029: checking assembler instructions" >&5
+echo "configure:9002: checking assembler instructions" >&5
     gcc_cv_as_instructions=
     if test x$gcc_cv_as != x; then
        set "filds fists" "filds mem; fists mem"
index 75fa2e2..0b79091 100644 (file)
@@ -3078,6 +3078,15 @@ changequote([,])dnl
                extra_headers=ppc-asm.h
                thread_file='vxworks'
                 ;;
+        powerpcle-wrs-vxworks*)
+                cpu_type=rs6000
+               xm_file="rs6000/xm-sysv4.h"
+               xm_defines="USG POSIX"
+                tm_file=rs6000/vxppcle.h
+                tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+               extra_headers=ppc-asm.h
+               thread_file='vxworks'
+                ;;
        powerpcle-*-sysv* | powerpcle-*-elf*)
                tm_file=rs6000/sysv4le.h
                xm_file="rs6000/xm-sysv4.h"
@@ -3106,27 +3115,6 @@ changequote([,])dnl
                fi
                extra_headers=ppc-asm.h
                ;;
-        powerpcle-*-winnt* )
-                tm_file=rs6000/win-nt.h
-                tmake_file=rs6000/t-winnt
-#               extra_objs=pe.o
-               if test x$enable_threads = xyes; then
-                       thread_file='win32'
-               fi
-               extra_headers=ppc-asm.h
-               ;;
-       powerpcle-*-pe | powerpcle-*-cygwin*)
-               tm_file=rs6000/cygwin.h
-               xm_file="rs6000/xm-cygwin.h ${xm_file}"
-               tmake_file=rs6000/t-winnt
-               xmake_file=rs6000/x-cygwin
-#              extra_objs=pe.o
-               if test x$enable_threads = xyes; then
-                       thread_file='win32'
-               fi
-               exeext=.exe
-               extra_headers=ppc-asm.h
-               ;;
        powerpcle-*-solaris2*)
                tm_file=rs6000/sol2.h
                xm_file="rs6000/xm-sysv4.h"
@@ -3171,12 +3159,7 @@ changequote([,])dnl
                else
                        tmake_file=rs6000/t-newas
                fi
-               if test "$gnu_ld" = yes
-               then
-                       xmake_file=rs6000/x-aix41-gld
-               else
-                       xmake_file=rs6000/x-aix41
-               fi
+               xmake_file=rs6000/x-aix41
                float_format=none
                use_collect2=yes
                ;;
@@ -3184,13 +3167,8 @@ changequote(,)dnl
        rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
 changequote([,])dnl
                tm_file=rs6000/aix43.h
-               if test x$host != x$target
-               then
-                       tmake_file=rs6000/t-xaix43
-               else
-                       tmake_file=rs6000/t-aix43
-               fi
-               xmake_file=rs6000/x-aix43
+               tmake_file=rs6000/t-aix43
+               xmake_file=rs6000/x-aix41
                float_format=none
                use_collect2=yes
                ;;
@@ -3198,13 +3176,8 @@ changequote(,)dnl
        rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
 changequote([,])dnl
                tm_file=rs6000/aix43.h
-               if test x$host != x$target
-               then
-                       tmake_file=rs6000/t-xaix43
-               else
-                       tmake_file=rs6000/t-aix43
-               fi
-               xmake_file=rs6000/x-aix43
+               tmake_file=rs6000/t-aix43
+               xmake_file=rs6000/x-aix41
                float_format=none
                use_collect2=yes
                ;;