]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Step 1 of VSX changes: Powerpc infrstructure changes
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Tue, 23 Jun 2009 20:15:15 +0000 (20:15 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Tue, 23 Jun 2009 20:15:15 +0000 (20:15 +0000)
Co-Authored-By: Pat Haugen <pthaugen@us.ibm.com>
Co-Authored-By: Revital Eres <eres@il.ibm.com>
From-SVN: r148869

21 files changed:
gcc/ChangeLog
gcc/config.in
gcc/config/rs6000/aix53.h
gcc/config/rs6000/aix61.h
gcc/config/rs6000/driver-rs6000.c
gcc/config/rs6000/e500.h
gcc/config/rs6000/linux64.h
gcc/config/rs6000/linux64.opt
gcc/config/rs6000/rs6000-c.c
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/rs6000.opt
gcc/config/rs6000/spe.md
gcc/config/rs6000/sync.md
gcc/config/rs6000/sysv4.h
gcc/config/rs6000/sysv4.opt
gcc/config/rs6000/t-rs6000
gcc/configure
gcc/configure.ac

index 4c20942c251f8db7d4c8e9b8506762330ba947a5..ea2ca5304ca073796b1181bca116af8246a0a3be 100644 (file)
@@ -1,3 +1,181 @@
+2009-06-23  Michael Meissner  <meissner@linux.vnet.ibm.com>
+           Pat Haugen  <pthaugen@us.ibm.com>
+           Revital1 Eres <ERES@il.ibm.com>
+
+       * config.in (HAVE_AS_POPCNTD): Add default definition.
+       (HAVE_AS_LWSYNC): Ditto.
+
+       * configure.ac (gcc_cv_as_powerpc_mfpgpr): Provide real binutils
+       release number.
+       (gcc_cv_as_powerpc_cmpb): Ditto.
+       (gcc_cv_as_powerpc_dfp): Ditto.
+       (gcc_cv_as_powerpc_vsx): Ditto.
+       (gcc_cv_as_powerpc_popcntd): Add feature test for assembler
+       supporting the popcntd/lwsync instructions.
+       (gcc_cv_as_powerpc_lwsync): Ditto.
+       * configure: Regenerate.
+
+       * config/rs6000/aix53.h (ASM_CPU_SPEC): Add support for
+       -mcpu=native and -mcpu=power7.
+       * config/rs6000/aix61.h (ASM_CPU_SPEC): Ditto.
+
+       * config/rs6000/linux64.opt (-mprofile-kernel): Move switch to be
+       a variable instead of a mask to reduce the number of mask bits.
+       * config/rs6000/sysv4.opt (-mbit-align): Ditto.
+       (-mbit-word): Ditto.
+       (-mregnames): Ditto.
+       * config/rs6000/rs6000.opt (-mupdate): Ditto.
+       (-mfused-madd): Ditto.
+
+       * config/rs6000/rs6000.opt (-mpopcntd): New switch for non-VSX ISA
+       2.06 instructions.
+       (-mvsx): New switch for VSX instructions.
+       (-misel): Move from a variable to a mask to allow it to be set by
+       -mcpu=.
+
+       * config/rs6000/rs6000-protos.h (rs6000_hard_regno_nregs): Change
+       function declaration to an array declaration.
+       (rs6000_hard_regno_nregs): New external array declaration.
+
+       * config/rs6000/t-rs6000 (MD_INCLUDES): Define, add all of the .md
+       files included by rs6000.md.
+
+       * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Use
+       SET_PROFILE_KERNEL macro to reset the -mprofile-kernel switch.
+
+       * config/rs6000/rs6000.c (rs6000_isel): Delete, -misel moved to be
+       a target mask.
+       (rs6000_debug_reg): New -mdebug= variables.
+       (rs6000_debug_addr): Ditto.
+       (rs6000_debug_cost): Ditto.
+       (rs6000_pmode): New variable to hold Pmode.
+       (rs6000_pointer_size): New variable to hold POINTER_SIZE.
+       (rs6000_class_max_nregs): New array to hold CLASS_MAX_NREGS
+       calculated at compiler start.
+       (rs6000_hard_regno_nregs): Change function to an array which holds
+       HARD_REGNO_NREGS calculated at compiler start.
+       (rs6000_explicit_options): Delete isel field.
+       (rs6000_vector_unit): New array to hold which vector unit
+       supports arithmetic options for a given type.
+       (rs6000_vector_mem): New array to hold which vector unit supports
+       memory reference operations for a given type.
+       (rs6000_vector_align): New array to given the alignment of each
+       vector type.
+       (power7_cost): New basic costs for power7.
+       (SET_PROFILE_KERNEL): New macro for resetting -mprofile-kernel.
+       (rs6000_hard_regno_nregs_internal): New function, moved from
+       HARD_REGNO_NREGS, to calculate the number of registers each hard
+       register takes for each type.
+       (rs6000_debug_reg_print): New function for -mdebug=reg support.
+       (rs6000_debug_vector_unit): New array, map rs6000_vector to
+       string.
+       (+rs6000_init_hard_regno_mode_ok): New function, move calculation
+       of HARD_REGNO_NREGS, CLASS_MAX_NREGS, REGNO_REG_CLASS, and vector
+       unit information here so it is calculated once at compiler startup
+       time.
+       (rs6000_override_options): Make -misel a target mask.  Add more
+       power7 target masks.  Setup Pmode and POINTER_SIZE.  Add initial
+       VSX support.  Add support for -mdebug=reg, -mdebug=addr, and
+       -mdebug=cost.
+       (POWERPC_MASKS): Add MASK_POPCNTD, MASK_VSX, and MASK_ISEL.
+       (rs6000_handle_option): Move -misel from variable to target mask.
+       (rs6000_builtin_mask_for_load): Add VSX support.
+       (rs6000_conditional_register_usage): Ditto.
+       (USE_ALTIVEC_FOR_ARG_P): Ditto.
+       (function_arg_boundary): Ditto.
+       (rs6000_expand_builtin): Ditto.
+       (def_builtin): Make abort message a little friendlier.
+       (rs6000_emit_int_cmove): Add support for 64-bit isel.
+
+       * config/rs6000/rs6000.h (ASM_CPU_POWER7_SPEC): Depend on the
+       assembler support the popcntd instruction instead of a vsx
+       instruction to enable power7 support.
+       (ASM_CPU_SPEC): Add support for -mcpu=native and -mcpu=power7.
+       (EXTRA_SPECS): Add ASM_CPU_NATIVE_SPEC to allow passing the right
+       option to the assembler if -mcpu=native.
+       (ASM_CPU_NATIVE_SPEC): Ditto.
+       (TARGET_POPCNTD): If assembler doesn't support popcntd, turn off
+       ISA 2.06 features.
+       (TARGET_LWSYNC_INSTRUCTION): Define whether it is safe to issue
+       the lwsync instruction.
+       (enum processor_type): Add PROCESSOR_POWER7.
+       (rs6000_debug_reg): New -mdebug= options.
+       (rs6000_debug_addr): Ditto.
+       (rs6000_debug_cost): Ditto.
+       (rs6000_isel): Delete.
+       (enum rs6000_vector): New enum to say what vector unit we have.
+       (VECTOR_UNIT_*): New macros to say which vector unit has
+       arithmetic operations for a given type.
+       (VECTOR_MEM_*): New macros to say which vector unit has memory
+       operations for a given type.
+       (TARGET_LDBRX): Whether the machine supports the ldbrx
+       instruction.
+       (TARGET_ISEL): Delete, -misel moved to be a mask.
+       (TARGET_ISEL64): New macro for 64-bit isel support.
+       (UNITS_PER_VSX_WORD): New macro.
+       (POINTER_SIZE): Move to be an external variable, rather than
+       calculating whether we are generating 32 ot 64-bit code.
+       (Pmode): Ditto.
+       (STACK_BOUNDARY): Add VSX support.
+       (LOCAL_ALIGNMENT): Ditto.
+       (SLOW_UNALIGNED_ACCESS): Ditto.
+       (VSX_REGNO_P): New macro for VSX support.
+       (VFLOAT_REGNO_P): Ditto.
+       (VINT_REGNO_P): Ditto.
+       (VLOGICAL_REGNO_P): Ditto.
+       (VSX_VECTOR_MODE): Ditto.
+       (VSX_SCALAR_MODE): Ditto.
+       (VSX_MODE): Ditto.
+       (VSX_MOVE_MODE): Ditto.
+       (VSX_REG_CLASS_P): Ditto.
+       (HARD_REGNO_NREGS): Instead of calling a function, use an array
+       lookup.
+       (UNITS_PER_SIMD_WORD): Add VSX support.
+       (MODES_TIEABLE_P): Ditto.
+       (STARTING_FRAME_OFFSET): Ditto.
+       (STACK_DYNAMIC_OFFSET): Ditto.
+       (EPILOGUE_USES): Ditto.
+       (REGNO_REG_CLASS): Move to array lookup.
+       (CLASS_MAX_NREGS): Ditto.
+       (rs6000_vector_reg_class): Add declaration.
+       (ADDITIONAL_REGISTER_NAMES): Add VSX names for the registers that
+       overlap with the floating point and Altivec registers.
+
+       * config/rs6000/e500.h (CHECK_E500_OPTIONS): Disallow -mvsx.
+
+       * config/rs6000/driver-rs6000.c (asm_names): New static array to
+       give the appropriate asm switches if -mcpu=native.
+       (host_detect_local_cpu): Add support for "asm".
+       (host_detect_local_cpu): Follow GNU code guidelines for name.
+
+       * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Move
+       -mbit-word to a variable instead of being a target mask.
+
+       * config/rs6000/sync.md (lwsync): If the assembler supports it,
+       emit the lwsync instruction instead of emitting the instruction as
+       an integer constant.
+
+       * config/rs6000/spe.md (spe_fixuns_truncdfsi2): Rename from
+       fixuns_trundfsi2, move expander into rs6000.md.
+
+       * config/rs6000/rs6000.md (cpu): Add power7.
+       (sel, *ptrsize): New mode attributes for 32/64-bit isel.
+       (logical predicate patterns): Change the single instruction
+       primitives that set CR0 to be fast_compare instead of compare.
+       (norsi*): Ditto.
+       (popcntwsi2): Add support for ISA 2.06 popcount instructions.
+       (popcntddi2): Ditto.
+       (popcount<mode>): Ditto.
+       (floating multiply/add insns): Name the floating point
+       multiply/add insns.
+       (isel_signed_<mode>): Add support for -misel on 64-bit systems.
+       (isel_unsigned_<mode>): Ditto.
+       (fixuns_trundfsi2): Move expander here from spe.md.
+       (smindi3): Define if we have -misel on 64-bit systems.
+       (smaxdi3): Ditto.
+       (umindi3): Ditto.
+       (umaxdi3): Ditto.
+
 2009-06-23  Anatoly Sokolov  <aesok@post.ru>
 
        * config.gcc (avr-*-rtems*, avr-*-*): Set extra_gcc_objs and
index adccc18506fd1edf40260a211dc87cd92a910f5f..cc0202beec27258658853331cd5adf0ae73a4b8c 100644 (file)
 #endif
 
 
-/* Define if your assembler supports popcntb field. */
+/* Define if your assembler supports popcntb instruction. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_POPCNTB
 #endif
 
 
+/* Define if your assembler supports popcntd instruction. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_POPCNTD
+#endif
+
+/* Define if your assembler supports lwsync instruction. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_LWSYNC
+#endif
+
+
 /* Define if your assembler supports .register. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_REGISTER_PSEUDO_OP
index 6172e76aad24d5ef8f2467332da155cb95c42f2a..b7b1eec9adf952e296233d3932c9527c70b92d16 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 POWER running AIX V5.3.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by David Edelsohn (edelsohn@gnu.org).
 
@@ -57,20 +57,24 @@ do {                                                                        \
 #undef ASM_SPEC
 #define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
 
-/* Common ASM definitions used by ASM_SPEC amongst the various targets
-   for handling -mcpu=xxx switches.  */
+/* Common ASM definitions used by ASM_SPEC amongst the various targets for
+   handling -mcpu=xxx switches.  There is a parallel list in driver-rs6000.c to
+   provide the default assembler options if the user uses -mcpu=native, so if
+   you make changes here, make them there also.  */
 #undef ASM_CPU_SPEC
 #define ASM_CPU_SPEC \
 "%{!mcpu*: %{!maix64: \
   %{mpowerpc64: -mppc64} \
   %{maltivec: -m970} \
   %{!maltivec: %{!mpower64: %(asm_default)}}}} \
+%{mcpu=native: %(asm_cpu_native)} \
 %{mcpu=power3: -m620} \
 %{mcpu=power4: -mpwr4} \
 %{mcpu=power5: -mpwr5} \
 %{mcpu=power5+: -mpwr5x} \
 %{mcpu=power6: -mpwr6} \
 %{mcpu=power6x: -mpwr6} \
+%{mcpu=power7: -mpwr7} \
 %{mcpu=powerpc: -mppc} \
 %{mcpu=rs64a: -mppc} \
 %{mcpu=603: -m603} \
index c0899d8c5137ff716830caa33025af567c8c7374..048486b108b78ee6fdcb746d2eda072268283693 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 POWER running AIX V6.1.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by David Edelsohn (edelsohn@gnu.org).
 
@@ -57,20 +57,24 @@ do {                                                                        \
 #undef ASM_SPEC
 #define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
 
-/* Common ASM definitions used by ASM_SPEC amongst the various targets
-   for handling -mcpu=xxx switches.  */
+/* Common ASM definitions used by ASM_SPEC amongst the various targets for
+   handling -mcpu=xxx switches.  There is a parallel list in driver-rs6000.c to
+   provide the default assembler options if the user uses -mcpu=native, so if
+   you make changes here, make them there also.  */
 #undef ASM_CPU_SPEC
 #define ASM_CPU_SPEC \
 "%{!mcpu*: %{!maix64: \
   %{mpowerpc64: -mppc64} \
   %{maltivec: -m970} \
   %{!maltivec: %{!mpower64: %(asm_default)}}}} \
+%{mcpu=native: %(asm_cpu_native)} \
 %{mcpu=power3: -m620} \
 %{mcpu=power4: -mpwr4} \
 %{mcpu=power5: -mpwr5} \
 %{mcpu=power5+: -mpwr5x} \
 %{mcpu=power6: -mpwr6} \
 %{mcpu=power6x: -mpwr6} \
+%{mcpu=power7: -mpwr7} \
 %{mcpu=powerpc: -mppc} \
 %{mcpu=rs64a: -mppc} \
 %{mcpu=603: -m603} \
index 3f5524ea08a526129a8b35a43ee4450dbf096f0f..11e76ea968f83886633b9de1814b68ff858b5e25 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines for the gcc driver.
-   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -343,47 +343,156 @@ detect_processor_aix (void)
 #endif /* _AIX */
 
 
+/*
+ * Array to map -mcpu=native names to the switches passed to the assembler.
+ * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here
+ * should be made there as well.
+ */
+
+struct asm_name {
+  const char *cpu;
+  const char *asm_sw;
+};
+
+static const struct asm_name asm_names[] = {
+#if defined (_AIX)
+  { "power3",  "-m620" },
+  { "power4",  "-mpwr4" },
+  { "power5",  "-mpwr5" },
+  { "power5+", "-mpwr5x" },
+  { "power6",  "-mpwr6" },
+  { "power6x", "-mpwr6" },
+  { "power7",  "-mpwr7" },
+  { "powerpc", "-mppc" },
+  { "rs64a",   "-mppc" },
+  { "603",     "-m603" },
+  { "603e",    "-m603" },
+  { "604",     "-m604" },
+  { "604e",    "-m604" },
+  { "620",     "-m620" },
+  { "630",     "-m620" },
+  { "970",     "-m970" },
+  { "G5",      "-m970" },
+  { NULL,      "\
+%{!maix64: \
+%{mpowerpc64: -mppc64} \
+%{maltivec: -m970} \
+%{!maltivec: %{!mpower64: %(asm_default)}}}" },
+
+#else
+  { "common",  "-mcom" },
+  { "cell",    "-mcell" },
+  { "power",   "-mpwr" },
+  { "power2",  "-mpwrx" },
+  { "power3",  "-mppc64" },
+  { "power4",  "-mpower4" },
+  { "power5",  "%(asm_cpu_power5)" },
+  { "power5+", "%(asm_cpu_power5)" },
+  { "power6",  "%(asm_cpu_power6) -maltivec" },
+  { "power6x", "%(asm_cpu_power6) -maltivec" },
+  { "power7",  "%(asm_cpu_power7)" },
+  { "powerpc", "-mppc" },
+  { "rios",    "-mpwr" },
+  { "rios1",   "-mpwr" },
+  { "rios2",   "-mpwrx" },
+  { "rsc",     "-mpwr" },
+  { "rsc1",    "-mpwr" },
+  { "rs64a",   "-mppc64" },
+  { "401",     "-mppc" },
+  { "403",     "-m403" },
+  { "405",     "-m405" },
+  { "405fp",   "-m405" },
+  { "440",     "-m440" },
+  { "440fp",   "-m440" },
+  { "464",     "-m440" },
+  { "464fp",   "-m440" },
+  { "505",     "-mppc" },
+  { "601",     "-m601" },
+  { "602",     "-mppc" },
+  { "603",     "-mppc" },
+  { "603e",    "-mppc" },
+  { "ec603e",  "-mppc" },
+  { "604",     "-mppc" },
+  { "604e",    "-mppc" },
+  { "620",     "-mppc64" },
+  { "630",     "-mppc64" },
+  { "740",     "-mppc" },
+  { "750",     "-mppc" },
+  { "G3",      "-mppc" },
+  { "7400",    "-mppc -maltivec" },
+  { "7450",    "-mppc -maltivec" },
+  { "G4",      "-mppc -maltivec" },
+  { "801",     "-mppc" },
+  { "821",     "-mppc" },
+  { "823",     "-mppc" },
+  { "860",     "-mppc" },
+  { "970",     "-mpower4 -maltivec" },
+  { "G5",      "-mpower4 -maltivec" },
+  { "8540",    "-me500" },
+  { "8548",    "-me500" },
+  { "e300c2",  "-me300" },
+  { "e300c3",  "-me300" },
+  { "e500mc",  "-me500mc" },
+  { NULL,      "\
+%{mpower: %{!mpower2: -mpwr}} \
+%{mpower2: -mpwrx} \
+%{mpowerpc64*: -mppc64} \
+%{!mpowerpc64*: %{mpowerpc*: -mppc}} \
+%{mno-power: %{!mpowerpc*: -mcom}} \
+%{!mno-power: %{!mpower*: %(asm_default)}}" },
+#endif
+};
+
 /* This will be called by the spec parser in gcc.c when it sees
    a %:local_cpu_detect(args) construct.  Currently it will be called
    with either "arch" or "tune" as argument depending on if -march=native
    or -mtune=native is to be substituted.
 
+   Additionally it will be called with "asm" to select the appropriate flags
+   for the assembler.
+
    It returns a string containing new command line parameters to be
    put at the place of the above two options, depending on what CPU
    this is executed.
 
    ARGC and ARGV are set depending on the actual arguments given
    in the spec.  */
-const char
-*host_detect_local_cpu (int argc, const char **argv)
+const char *
+host_detect_local_cpu (int argc, const char **argv)
 {
   const char *cpu = NULL;
   const char *cache = "";
   const char *options = "";
   bool arch;
+  bool assembler;
+  size_t i;
 
   if (argc < 1)
     return NULL;
 
   arch = strcmp (argv[0], "cpu") == 0;
-  if (!arch && strcmp (argv[0], "tune"))
+  assembler = (!arch && strcmp (argv[0], "asm") == 0);
+  if (!arch && !assembler && strcmp (argv[0], "tune"))
     return NULL;
 
+  if (! assembler)
+    {
 #if defined (_AIX)
-  cache = detect_caches_aix ();
+      cache = detect_caches_aix ();
 #elif defined (__APPLE__)
-  cache = detect_caches_darwin ();
+      cache = detect_caches_darwin ();
 #elif defined (__FreeBSD__)
-  cache = detect_caches_freebsd ();
-  /* FreeBSD PPC does not provide any cache information yet.  */
-  cache = "";
+      cache = detect_caches_freebsd ();
+      /* FreeBSD PPC does not provide any cache information yet.  */
+      cache = "";
 #elif defined (__linux__)
-  cache = detect_caches_linux ();
-  /* PPC Linux does not provide any cache information yet.  */
-  cache = "";
+      cache = detect_caches_linux ();
+      /* PPC Linux does not provide any cache information yet.  */
+      cache = "";
 #else
-  cache = "";
+      cache = "";
 #endif
+    }
 
 #if defined (_AIX)
   cpu = detect_processor_aix ();
@@ -397,6 +506,17 @@ const char
   cpu = "powerpc";
 #endif
 
+  if (assembler)
+    {
+      for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++)
+       {
+         if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu))
+           return asm_names[i].asm_sw;
+       }
+
+      return NULL;
+    }
+
   return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
 }
 
@@ -404,7 +524,8 @@ const char
 
 /* If we aren't compiling with GCC we just provide a minimal
    default value.  */
-const char *host_detect_local_cpu (int argc, const char **argv)
+const char *
+host_detect_local_cpu (int argc, const char **argv)
 {
   const char *cpu;
   bool arch;
index 81fb472e7a784b27df697c7187a523dff1e2a2f5..05b20ad1139571dd8c7108754bab0952dc69761e 100644 (file)
@@ -1,5 +1,6 @@
 /* Enable E500 support.
-   Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009 Free Software
+   Foundation, Inc.
    This file is part of GCC.
 
    GCC is free software; you can redistribute it and/or modify it
@@ -37,6 +38,8 @@
       {                                                                        \
        if (TARGET_ALTIVEC)                                             \
          error ("AltiVec and E500 instructions cannot coexist");       \
+       if (TARGET_VSX)                                                 \
+         error ("VSX and E500 instructions cannot coexist");           \
        if (TARGET_64BIT)                                               \
          error ("64-bit E500 not supported");                          \
        if (TARGET_HARD_FLOAT && TARGET_FPRS)                           \
index c3193dcfe0de1fe82b6a2b0a04e97fce3842c4fc..94d18aee1dafdec8c02386c7665815fe357762b0 100644 (file)
@@ -119,7 +119,7 @@ extern int dot_symbols;
            error (INVALID_32BIT, "32");                        \
          if (TARGET_PROFILE_KERNEL)                            \
            {                                                   \
-             target_flags &= ~MASK_PROFILE_KERNEL;             \
+             SET_PROFILE_KERNEL (0);                           \
              error (INVALID_32BIT, "profile-kernel");          \
            }                                                   \
        }                                                       \
index f408eb88dc8e1085c9e21badbf4bbc2bfcabdb28..1eac7382aa022b50833e48c91da53922bd63e724 100644 (file)
@@ -1,6 +1,6 @@
 ; Options for 64-bit PowerPC Linux.
 ;
-; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+; Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
 ; Contributed by Aldy Hernandez <aldy@quesejoda.com>.
 ;
 ; This file is part of GCC.
@@ -20,5 +20,5 @@
 ; <http://www.gnu.org/licenses/>.
 
 mprofile-kernel
-Target Report Mask(PROFILE_KERNEL)
+Target Report Var(TARGET_PROFILE_KERNEL)
 Call mcount for profiling before a function prologue
index 8a39b9e9f8458a2355199d8801288a077bd063a9..d1ab9da9b2932ddc9c4ee0b54b762805a4ca15d3 100644 (file)
@@ -284,6 +284,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
     builtin_define ("_ARCH_PWR6X");
   if (! TARGET_POWER && ! TARGET_POWER2 && ! TARGET_POWERPC)
     builtin_define ("_ARCH_COM");
+  if (TARGET_POPCNTD)
+    builtin_define ("_ARCH_PWR7");
   if (TARGET_ALTIVEC)
     {
       builtin_define ("__ALTIVEC__");
@@ -326,6 +328,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
   /* Used by libstdc++.  */
   if (TARGET_NO_LWSYNC)
     builtin_define ("__NO_LWSYNC__");
+  if (TARGET_VSX)
+    builtin_define ("__VSX__");
 
   /* May be overridden by target configuration.  */
   RS6000_CPU_CPP_ENDIAN_BUILTINS();
index 1b68d440eb8ade399ea0a8db1a3525f9ca19f710..731349e04d23609edec5634a9b573ead4c8b2c52 100644 (file)
@@ -168,7 +168,6 @@ extern int rs6000_register_move_cost (enum machine_mode,
                                      enum reg_class, enum reg_class);
 extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
 extern bool rs6000_tls_referenced_p (rtx);
-extern int rs6000_hard_regno_nregs (int, enum machine_mode);
 extern void rs6000_conditional_register_usage (void);
 
 /* Declare functions in rs6000-c.c */
@@ -187,4 +186,6 @@ const char * rs6000_xcoff_strip_dollar (const char *);
 void rs6000_final_prescan_insn (rtx, rtx *operand, int num_operands);
 
 extern bool rs6000_hard_regno_mode_ok_p[][FIRST_PSEUDO_REGISTER];
+extern unsigned char rs6000_class_max_nregs[][LIM_REG_CLASSES];
+extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER];
 #endif  /* rs6000-protos.h */
index 9465c9f945a1f6b6edf83fc0e9121c78a7761f9e..0263f91cc2f1596e94a08232aaee74e7eaa49e4e 100644 (file)
@@ -178,9 +178,6 @@ int rs6000_spe;
 /* Nonzero if we want SPE ABI extensions.  */
 int rs6000_spe_abi;
 
-/* Nonzero to use isel instructions.  */
-int rs6000_isel;
-
 /* Nonzero if floating point operations are done in the GPRs.  */
 int rs6000_float_gprs = 0;
 
@@ -222,12 +219,33 @@ int dot_symbols;
 const char *rs6000_debug_name;
 int rs6000_debug_stack;                /* debug stack applications */
 int rs6000_debug_arg;          /* debug argument handling */
+int rs6000_debug_reg;          /* debug register classes */
+int rs6000_debug_addr;         /* debug memory addressing */
+int rs6000_debug_cost;         /* debug rtx_costs */
+
+/* Specify the machine mode that pointers have.  After generation of rtl, the
+   compiler makes no further distinction between pointers and any other objects
+   of this machine mode.  The type is unsigned since not all things that
+   include rs6000.h also include machmode.h.  */
+unsigned rs6000_pmode;
+
+/* Width in bits of a pointer.  */
+unsigned rs6000_pointer_size;
+
 
 /* Value is TRUE if register/mode pair is acceptable.  */
 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
 
-/* Built in types.  */
+/* Maximum number of registers needed for a given register class and mode.  */
+unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
+
+/* How many registers are needed for a given register and mode.  */
+unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
 
+/* Map register number to register class.  */
+enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
+
+/* Built in types.  */
 tree rs6000_builtin_types[RS6000_BTI_MAX];
 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
 
@@ -265,7 +283,6 @@ static struct {
   bool altivec_abi;            /* True if -mabi=altivec/no-altivec used.  */
   bool spe;                    /* True if -mspe= was used.  */
   bool float_gprs;             /* True if -mfloat-gprs= was used.  */
-  bool isel;                   /* True if -misel was used. */
   bool long_double;            /* True if -mlong-double- was used.  */
   bool ieee;                   /* True if -mabi=ieee/ibmlongdouble used.  */
   bool vrsave;                 /* True if -mvrsave was used.  */
@@ -281,6 +298,14 @@ struct builtin_description
   const char *const name;
   const enum rs6000_builtins code;
 };
+
+/* Describe the vector unit used for modes.  */
+enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
+enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
+enum reg_class rs6000_vector_reg_class[NUM_MACHINE_MODES];
+
+/* Describe the alignment of a vector.  */
+int rs6000_vector_align[NUM_MACHINE_MODES];
 \f
 /* Target cpu costs.  */
 
@@ -744,6 +769,25 @@ struct processor_costs power6_cost = {
   16,                  /* prefetch streams */
 };
 
+/* Instruction costs on POWER7 processors.  */
+static const
+struct processor_costs power7_cost = {
+  COSTS_N_INSNS (2),   /* mulsi */
+  COSTS_N_INSNS (2),   /* mulsi_const */
+  COSTS_N_INSNS (2),   /* mulsi_const9 */
+  COSTS_N_INSNS (2),   /* muldi */
+  COSTS_N_INSNS (18),  /* divsi */
+  COSTS_N_INSNS (34),  /* divdi */
+  COSTS_N_INSNS (3),   /* fp */
+  COSTS_N_INSNS (3),   /* dmul */
+  COSTS_N_INSNS (13),  /* sdiv */
+  COSTS_N_INSNS (16),  /* ddiv */
+  128,                 /* cache line size */
+  32,                  /* l1 cache */
+  256,                 /* l2 cache */
+  12,                  /* prefetch streams */
+};
+
 \f
 static bool rs6000_function_ok_for_sibcall (tree, tree);
 static const char *rs6000_invalid_within_doloop (const_rtx);
@@ -1055,6 +1099,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #endif
 #ifndef TARGET_PROFILE_KERNEL
 #define TARGET_PROFILE_KERNEL 0
+#define SET_PROFILE_KERNEL(N)
+#else
+#define SET_PROFILE_KERNEL(N) TARGET_PROFILE_KERNEL = (N)
 #endif
 
 /* The VRSAVE bitmask puts bit %v0 as the most significant bit.  */
@@ -1312,6 +1359,46 @@ static const struct attribute_spec rs6000_attribute_table[] =
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
+/* Return number of consecutive hard regs needed starting at reg REGNO
+   to hold something of mode MODE.
+   This is ordinarily the length in words of a value of mode MODE
+   but can be less for certain modes in special long registers.
+
+   For the SPE, GPRs are 64 bits but only 32 bits are visible in
+   scalar instructions.  The upper 32 bits are only available to the
+   SIMD instructions.
+
+   POWER and PowerPC GPRs hold 32 bits worth;
+   PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
+
+static int
+rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
+{
+  unsigned HOST_WIDE_INT reg_size;
+
+  if (FP_REGNO_P (regno))
+    reg_size = UNITS_PER_FP_WORD;
+
+  else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+    reg_size = UNITS_PER_SPE_WORD;
+
+  else if (ALTIVEC_REGNO_P (regno))
+    reg_size = UNITS_PER_ALTIVEC_WORD;
+
+  /* The value returned for SCmode in the E500 double case is 2 for
+     ABI compatibility; storing an SCmode value in a single register
+     would require function_arg and rs6000_spe_function_arg to handle
+     SCmode so as to pass the value correctly in a pair of
+     registers.  */
+  else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
+          && !DECIMAL_FLOAT_MODE_P (mode))
+    reg_size = UNITS_PER_FP_WORD;
+
+  else
+    reg_size = UNITS_PER_WORD;
+
+  return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
+}
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode
    MODE.  */
@@ -1356,16 +1443,267 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
   return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
 }
 
-/* Initialize rs6000_hard_regno_mode_ok_p table.  */
+/* Print interesting facts about registers.  */
 static void
-rs6000_init_hard_regno_mode_ok (void)
+rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
 {
   int r, m;
 
+  for (r = first_regno; r <= last_regno; ++r)
+    {
+      const char *comma = "";
+      int len;
+
+      if (first_regno == last_regno)
+       fprintf (stderr, "%s:\t", reg_name);
+      else
+       fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
+
+      len = 8;
+      for (m = 0; m < NUM_MACHINE_MODES; ++m)
+       if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
+         {
+           if (len > 70)
+             {
+               fprintf (stderr, ",\n\t");
+               len = 8;
+               comma = "";
+             }
+
+           if (rs6000_hard_regno_nregs[m][r] > 1)
+             len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
+                            rs6000_hard_regno_nregs[m][r]);
+           else
+             len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
+
+           comma = ", ";
+         }
+
+      if (call_used_regs[r])
+       {
+         if (len > 70)
+           {
+             fprintf (stderr, ",\n\t");
+             len = 8;
+             comma = "";
+           }
+
+         len += fprintf (stderr, "%s%s", comma, "call-used");
+         comma = ", ";
+       }
+
+      if (fixed_regs[r])
+       {
+         if (len > 70)
+           {
+             fprintf (stderr, ",\n\t");
+             len = 8;
+             comma = "";
+           }
+
+         len += fprintf (stderr, "%s%s", comma, "fixed");
+         comma = ", ";
+       }
+
+      if (len > 70)
+       {
+         fprintf (stderr, ",\n\t");
+         comma = "";
+       }
+
+      fprintf (stderr, "%sregno = %d\n", comma, r);
+    }
+}
+
+/* Map enum rs6000_vector to string.  */
+static const char *
+rs6000_debug_vector_unit[] = {
+  "none",
+  "altivec",
+  "vsx",
+  "paired",
+  "spe",
+  "other"
+};
+
+/* Initialize the various global tables that are based on register size.  */
+static void
+rs6000_init_hard_regno_mode_ok (void)
+{
+  int r, m, c;
+  bool float_p = (TARGET_HARD_FLOAT && TARGET_FPRS);
+
+  /* Precalculate REGNO_REG_CLASS.  */
+  rs6000_regno_regclass[0] = GENERAL_REGS;
+  for (r = 1; r < 32; ++r)
+    rs6000_regno_regclass[r] = BASE_REGS;
+
+  for (r = 32; r < 64; ++r)
+    rs6000_regno_regclass[r] = FLOAT_REGS;
+
+  for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
+    rs6000_regno_regclass[r] = NO_REGS;
+
+  for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
+    rs6000_regno_regclass[r] = ALTIVEC_REGS;
+
+  rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
+  for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
+    rs6000_regno_regclass[r] = CR_REGS;
+
+  rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
+  rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
+  rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
+  rs6000_regno_regclass[XER_REGNO] = XER_REGS;
+  rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
+  rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
+  rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
+  rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
+  rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
+  rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
+
+  /* Precalculate vector information, this must be set up before the
+     rs6000_hard_regno_nregs_internal below.  */
+  for (m = 0; m < NUM_MACHINE_MODES; ++m)
+    {
+      rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
+      rs6000_vector_reg_class[m] = NO_REGS;
+    }
+
+  /* V4SF mode, Altivec only.  */
+  if (float_p && TARGET_ALTIVEC)
+    {
+      rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
+      rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
+      rs6000_vector_align[V4SFmode] = 128;
+    }
+
+  /* V16QImode, V8HImode, V4SImode are Altivec only.  */
+  if (TARGET_ALTIVEC)
+    {
+      rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
+      rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
+      rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
+
+      rs6000_vector_reg_class[V16QImode] = ALTIVEC_REGS;
+      rs6000_vector_reg_class[V8HImode] = ALTIVEC_REGS;
+      rs6000_vector_reg_class[V4SImode] = ALTIVEC_REGS;
+
+      rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
+      rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
+      rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
+      rs6000_vector_align[V4SImode] = 128;
+      rs6000_vector_align[V8HImode] = 128;
+      rs6000_vector_align[V16QImode] = 128;
+    }
+
+  /* V2DImode, prefer vsx over altivec, since the main use will be for
+     vectorized floating point conversions.  */
+  if (TARGET_ALTIVEC)
+    {
+      rs6000_vector_mem[V2DImode] = VECTOR_ALTIVEC;
+      rs6000_vector_unit[V2DImode] = VECTOR_NONE;
+      rs6000_vector_reg_class[V2DImode] = ALTIVEC_REGS;
+      rs6000_vector_align[V2DImode] = 128;
+    }
+
+  /* TODO add SPE and paired floating point vector support.  */
+
+  /* Set the VSX register classes.  */
+  rs6000_vector_reg_class[V4SFmode]
+    = (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
+       ? ALTIVEC_REGS
+       : NO_REGS);
+
+  rs6000_vector_reg_class[V2DFmode] = NO_REGS;
+
+  rs6000_vector_reg_class[DFmode] = (!float_p ? NO_REGS : FLOAT_REGS);
+
+  /* Precalculate HARD_REGNO_NREGS.  */
+  for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
+    for (m = 0; m < NUM_MACHINE_MODES; ++m)
+      rs6000_hard_regno_nregs[m][r]
+       = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
+
+  /* Precalculate HARD_REGNO_MODE_OK.  */
   for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
     for (m = 0; m < NUM_MACHINE_MODES; ++m)
-      if (rs6000_hard_regno_mode_ok (r, (enum machine_mode) m))
+      if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
        rs6000_hard_regno_mode_ok_p[m][r] = true;
+
+  /* Precalculate CLASS_MAX_NREGS sizes.  */
+  for (c = 0; c < LIM_REG_CLASSES; ++c)
+    {
+      int reg_size;
+
+      if (c == ALTIVEC_REGS)
+       reg_size = UNITS_PER_ALTIVEC_WORD;
+
+      else if (c == FLOAT_REGS)
+       reg_size = UNITS_PER_FP_WORD;
+
+      else
+       reg_size = UNITS_PER_WORD;
+
+      for (m = 0; m < NUM_MACHINE_MODES; ++m)
+       rs6000_class_max_nregs[m][c]
+         = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
+    }
+
+  if (TARGET_E500_DOUBLE)
+    rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
+
+  if (TARGET_DEBUG_REG)
+    {
+      const char *nl = (const char *)0;
+
+      fprintf (stderr, "Register information: (last virtual reg = %d)\n",
+              LAST_VIRTUAL_REGISTER);
+      rs6000_debug_reg_print (0, 31, "gr");
+      rs6000_debug_reg_print (32, 63, "fp");
+      rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
+                             LAST_ALTIVEC_REGNO,
+                             "vs");
+      rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
+      rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
+      rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
+      rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
+      rs6000_debug_reg_print (XER_REGNO, XER_REGNO, "xer");
+      rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
+      rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
+      rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
+      rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
+
+      fprintf (stderr,
+              "\n"
+              "V16QI reg_class = %s\n"
+              "V8HI  reg_class = %s\n"
+              "V4SI  reg_class = %s\n"
+              "V2DI  reg_class = %s\n"
+              "V4SF  reg_class = %s\n"
+              "V2DF  reg_class = %s\n"
+              "DF    reg_class = %s\n\n",
+              reg_class_names[rs6000_vector_reg_class[V16QImode]],
+              reg_class_names[rs6000_vector_reg_class[V8HImode]],
+              reg_class_names[rs6000_vector_reg_class[V4SImode]],
+              reg_class_names[rs6000_vector_reg_class[V2DImode]],
+              reg_class_names[rs6000_vector_reg_class[V4SFmode]],
+              reg_class_names[rs6000_vector_reg_class[V2DFmode]],
+              reg_class_names[rs6000_vector_reg_class[DFmode]]);
+
+      for (m = 0; m < NUM_MACHINE_MODES; ++m)
+       if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
+         {
+           nl = "\n";
+           fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
+                    GET_MODE_NAME (m),
+                    rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
+                    rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
+         }
+
+      if (nl)
+       fputs (nl, stderr);
+    }
 }
 
 #if TARGET_MACHO
@@ -1495,12 +1833,15 @@ rs6000_override_options (const char *default_cpu)
         {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
         {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
         {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
-        {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
+        {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
+         | MASK_ISEL},
         /* 8548 has a dummy entry for now.  */
-        {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
+        {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
+         | MASK_ISEL},
         {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
         {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
-        {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+        {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
+         | MASK_ISEL},
         {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
         {"970", PROCESSOR_POWER4,
          POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
@@ -1533,9 +1874,10 @@ rs6000_override_options (const char *default_cpu)
          POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
          | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
          | MASK_MFPGPR},
-        {"power7", PROCESSOR_POWER5,
+        {"power7", PROCESSOR_POWER7,
          POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
-         | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
+         | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
+         | MASK_VSX},  /* Don't add MASK_ISEL by default */
         {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
         {"powerpc64", PROCESSOR_POWERPC64,
          POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
@@ -1562,9 +1904,22 @@ rs6000_override_options (const char *default_cpu)
     POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
                     | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
                     | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
-                    | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP)
+                    | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
+                    | MASK_POPCNTD | MASK_VSX | MASK_ISEL)
   };
 
+  /* Set the pointer size.  */
+  if (TARGET_POWERPC64)
+    {
+      rs6000_pmode = (int)DImode;
+      rs6000_pointer_size = 64;
+    }
+  else
+    {
+      rs6000_pmode = (int)SImode;
+      rs6000_pointer_size = 32;
+    }
+
   set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
 #ifdef OS_MISSING_POWERPC64
   if (OS_MISSING_POWERPC64)
@@ -1607,10 +1962,6 @@ rs6000_override_options (const char *default_cpu)
        }
     }
 
-  if ((TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC)
-      && !rs6000_explicit_options.isel)
-    rs6000_isel = 1;
-
   if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
       || rs6000_cpu == PROCESSOR_PPCE500MC)
     {
@@ -1655,15 +2006,55 @@ rs6000_override_options (const char *default_cpu)
        }
     }
 
+  /* Add some warnings for VSX.  Enable -maltivec unless the user explicitly
+     used -mno-altivec  */
+  if (TARGET_VSX)
+    {
+      const char *msg = NULL;
+      if (!TARGET_HARD_FLOAT || !TARGET_FPRS
+         || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
+       {
+         if (target_flags_explicit & MASK_VSX)
+           msg = N_("-mvsx requires hardware floating point");
+         else
+           target_flags &= ~ MASK_VSX;
+       }
+      else if (TARGET_PAIRED_FLOAT)
+       msg = N_("-mvsx and -mpaired are incompatible");
+      /* The hardware will allow VSX and little endian, but until we make sure
+        things like vector select, etc. work don't allow VSX on little endian
+        systems at this point.  */
+      else if (!BYTES_BIG_ENDIAN)
+       msg = N_("-mvsx used with little endian code");
+      else if (TARGET_AVOID_XFORM > 0)
+       msg = N_("-mvsx needs indexed addressing");
+
+      if (msg)
+       {
+         warning (0, msg);
+         target_flags &= ~ MASK_VSX;
+       }
+      else if (TARGET_VSX && !TARGET_ALTIVEC
+              && (target_flags_explicit & MASK_ALTIVEC) == 0)
+       target_flags |= MASK_ALTIVEC;
+    }
+
   /* Set debug flags */
   if (rs6000_debug_name)
     {
       if (! strcmp (rs6000_debug_name, "all"))
-       rs6000_debug_stack = rs6000_debug_arg = 1;
+       rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
+         = rs6000_debug_addr = rs6000_debug_cost = 1;
       else if (! strcmp (rs6000_debug_name, "stack"))
        rs6000_debug_stack = 1;
       else if (! strcmp (rs6000_debug_name, "arg"))
        rs6000_debug_arg = 1;
+      else if (! strcmp (rs6000_debug_name, "reg"))
+       rs6000_debug_reg = 1;
+      else if (! strcmp (rs6000_debug_name, "addr"))
+       rs6000_debug_addr = 1;
+      else if (! strcmp (rs6000_debug_name, "cost"))
+       rs6000_debug_cost = 1;
       else
        error ("unknown -mdebug-%s switch", rs6000_debug_name);
     }
@@ -1690,7 +2081,7 @@ rs6000_override_options (const char *default_cpu)
 #endif
 
   /* Enable Altivec ABI for AIX -maltivec.  */
-  if (TARGET_XCOFF && TARGET_ALTIVEC)
+  if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
     rs6000_altivec_abi = 1;
 
   /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux.  For
@@ -1699,7 +2090,7 @@ rs6000_override_options (const char *default_cpu)
   if (TARGET_ELF)
     {
       if (!rs6000_explicit_options.altivec_abi
-         && (TARGET_64BIT || TARGET_ALTIVEC))
+         && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
        rs6000_altivec_abi = 1;
 
       /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden.  */
@@ -1754,8 +2145,8 @@ rs6000_override_options (const char *default_cpu)
        rs6000_spe = 0;
       if (!rs6000_explicit_options.float_gprs)
        rs6000_float_gprs = 0;
-      if (!rs6000_explicit_options.isel)
-       rs6000_isel = 0;
+      if (!(target_flags_explicit & MASK_ISEL))
+       target_flags &= ~MASK_ISEL;
     }
 
   /* Detect invalid option combinations with E500.  */
@@ -1763,13 +2154,15 @@ rs6000_override_options (const char *default_cpu)
 
   rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
                        && rs6000_cpu != PROCESSOR_POWER5
-                        && rs6000_cpu != PROCESSOR_POWER6
+                       && rs6000_cpu != PROCESSOR_POWER6
+                       && rs6000_cpu != PROCESSOR_POWER7
                        && rs6000_cpu != PROCESSOR_CELL);
   rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
                         || rs6000_cpu == PROCESSOR_POWER5);
   rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
-                                 || rs6000_cpu == PROCESSOR_POWER5
-                                 || rs6000_cpu == PROCESSOR_POWER6);
+                                || rs6000_cpu == PROCESSOR_POWER5
+                                || rs6000_cpu == PROCESSOR_POWER6
+                                || rs6000_cpu == PROCESSOR_POWER7);
 
   rs6000_sched_restricted_insns_priority
     = (rs6000_sched_groups ? 1 : 0);
@@ -1966,6 +2359,10 @@ rs6000_override_options (const char *default_cpu)
        rs6000_cost = &power6_cost;
        break;
 
+      case PROCESSOR_POWER7:
+       rs6000_cost = &power7_cost;
+       break;
+
       default:
        gcc_unreachable ();
       }
@@ -2016,7 +2413,7 @@ rs6000_override_options (const char *default_cpu)
 static tree
 rs6000_builtin_mask_for_load (void)
 {
-  if (TARGET_ALTIVEC)
+  if (TARGET_ALTIVEC || TARGET_VSX)
     return altivec_builtin_mask_for_load;
   else
     return 0;
@@ -2246,6 +2643,7 @@ static bool
 rs6000_handle_option (size_t code, const char *arg, int value)
 {
   enum fpu_type_t fpu_type = FPU_NONE;
+  int isel;
 
   switch (code)
     {
@@ -2353,14 +2751,14 @@ rs6000_handle_option (size_t code, const char *arg, int value)
       rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
       break;
 
-    case OPT_misel:
-      rs6000_explicit_options.isel = true;
-      rs6000_isel = value;
-      break;
-
     case OPT_misel_:
-      rs6000_explicit_options.isel = true;
-      rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
+      target_flags_explicit |= MASK_ISEL;
+      isel = 0;
+      rs6000_parse_yes_no_option ("isel", arg, &isel);
+      if (isel)
+       target_flags |= MASK_ISEL;
+      else
+       target_flags &= ~MASK_ISEL;
       break;
 
     case OPT_mspe:
@@ -4584,43 +4982,6 @@ rs6000_offsettable_memref_p (rtx op)
   return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
 }
 
-/* Return number of consecutive hard regs needed starting at reg REGNO
-   to hold something of mode MODE.
-   This is ordinarily the length in words of a value of mode MODE
-   but can be less for certain modes in special long registers.
-
-   For the SPE, GPRs are 64 bits but only 32 bits are visible in
-   scalar instructions.  The upper 32 bits are only available to the
-   SIMD instructions.
-
-   POWER and PowerPC GPRs hold 32 bits worth;
-   PowerPC64 GPRs and FPRs point register holds 64 bits worth.  */
-
-int
-rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
-{
-  if (FP_REGNO_P (regno))
-    return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
-
-  if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
-    return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
-
-  if (ALTIVEC_REGNO_P (regno))
-    return
-      (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
-
-  /* The value returned for SCmode in the E500 double case is 2 for
-     ABI compatibility; storing an SCmode value in a single register
-     would require function_arg and rs6000_spe_function_arg to handle
-     SCmode so as to pass the value correctly in a pair of
-     registers.  */
-  if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
-      && !DECIMAL_FLOAT_MODE_P (mode))
-    return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
-
-  return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-}
-
 /* Change register usage conditional on target flags.  */
 void
 rs6000_conditional_register_usage (void)
@@ -4685,14 +5046,14 @@ rs6000_conditional_register_usage (void)
        = call_really_used_regs[14] = 1;
     }
 
-  if (!TARGET_ALTIVEC)
+  if (!TARGET_ALTIVEC && !TARGET_VSX)
     {
       for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
        fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
       call_really_used_regs[VRSAVE_REGNO] = 1;
     }
 
-  if (TARGET_ALTIVEC)
+  if (TARGET_ALTIVEC || TARGET_VSX)
     global_regs[VSCR_REGNO] = 1;
 
   if (TARGET_ALTIVEC_ABI)
@@ -5310,10 +5671,10 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
    && TARGET_HARD_FLOAT && TARGET_FPRS)
 
 /* Nonzero if we can use an AltiVec register to pass this arg.  */
-#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)     \
-  (ALTIVEC_VECTOR_MODE (MODE)                          \
-   && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG             \
-   && TARGET_ALTIVEC_ABI                               \
+#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED)             \
+  ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE))      \
+   && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG                     \
+   && TARGET_ALTIVEC_ABI                                       \
    && (NAMED))
 
 /* Return a nonzero value to say to return the function value in
@@ -5554,7 +5915,7 @@ function_arg_boundary (enum machine_mode mode, tree type)
               && int_size_in_bytes (type) >= 8
               && int_size_in_bytes (type) < 16))
     return 64;
-  else if (ALTIVEC_VECTOR_MODE (mode)
+  else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
           || (type && TREE_CODE (type) == VECTOR_TYPE
               && int_size_in_bytes (type) >= 16))
     return 128;
@@ -5700,6 +6061,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 
   if (TARGET_ALTIVEC_ABI
       && (ALTIVEC_VECTOR_MODE (mode)
+         || VSX_VECTOR_MODE (mode)
          || (type && TREE_CODE (type) == VECTOR_TYPE
              && int_size_in_bytes (type) == 16)))
     {
@@ -6294,6 +6656,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
       return gen_rtx_REG (mode, cum->vregno);
   else if (TARGET_ALTIVEC_ABI
           && (ALTIVEC_VECTOR_MODE (mode)
+              || VSX_VECTOR_MODE (mode)
               || (type && TREE_CODE (type) == VECTOR_TYPE
                   && int_size_in_bytes (type) == 16)))
     {
@@ -7192,7 +7555,8 @@ def_builtin (int mask, const char *name, tree type, int code)
   if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
     {
       if (rs6000_builtin_decls[code])
-       abort ();
+       fatal_error ("internal error: builtin function to %s already processed.",
+                    name);
 
       rs6000_builtin_decls[code] =
         add_builtin_function (name, type, code, BUILT_IN_MD,
@@ -9342,7 +9706,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
        return ret;
     }  
 
-  gcc_assert (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT);
+  gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
 
   /* Handle simple unary operations.  */
   d = (struct builtin_description *) bdesc_1arg;
@@ -13770,9 +14134,9 @@ static int
 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
 {
   rtx condition_rtx, cr;
+  enum machine_mode mode = GET_MODE (XEXP (op, 0));
 
-  /* All isel implementations thus far are 32-bits.  */
-  if (GET_MODE (XEXP (op, 0)) != SImode)
+  if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
     return 0;
 
   /* We still have to do the compare, because isel doesn't do a
@@ -13781,12 +14145,24 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
   condition_rtx = rs6000_generate_compare (op, SImode);
   cr = XEXP (condition_rtx, 0);
 
-  if (GET_MODE (cr) == CCmode)
-    emit_insn (gen_isel_signed (dest, condition_rtx,
-                               true_cond, false_cond, cr));
+  if (mode == SImode)
+    {
+      if (GET_MODE (cr) == CCmode)
+       emit_insn (gen_isel_signed_si (dest, condition_rtx,
+                                      true_cond, false_cond, cr));
+      else
+       emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
+                                        true_cond, false_cond, cr));
+    }
   else
-    emit_insn (gen_isel_unsigned (dest, condition_rtx,
-                                 true_cond, false_cond, cr));
+    {
+      if (GET_MODE (cr) == CCmode)
+       emit_insn (gen_isel_signed_di (dest, condition_rtx,
+                                      true_cond, false_cond, cr));
+      else
+       emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
+                                        true_cond, false_cond, cr));
+    }
 
   return 1;
 }
index c50060026c5b7b6f5f8cc4534b4c638f85eb4422..f4a5401670f9bf0acd9a61c3a51df79fa2b0d7b5 100644 (file)
 #define ASM_CPU_POWER6_SPEC "-mpower4 -maltivec"
 #endif
 
-#ifdef HAVE_AS_VSX
+#ifdef HAVE_AS_POPCNTD
 #define ASM_CPU_POWER7_SPEC "-mpower7"
 #else
 #define ASM_CPU_POWER7_SPEC "-mpower4 -maltivec"
 #endif
 
-/* Common ASM definitions used by ASM_SPEC among the various targets
-   for handling -mcpu=xxx switches.  */
+/* Common ASM definitions used by ASM_SPEC among the various targets for
+   handling -mcpu=xxx switches.  There is a parallel list in driver-rs6000.c to
+   provide the default assembler options if the user uses -mcpu=native, so if
+   you make changes here, make them also there.  */
 #define ASM_CPU_SPEC \
 "%{!mcpu*: \
   %{mpower: %{!mpower2: -mpwr}} \
@@ -93,6 +95,7 @@
   %{!mpowerpc64*: %{mpowerpc*: -mppc}} \
   %{mno-power: %{!mpowerpc*: -mcom}} \
   %{!mno-power: %{!mpower*: %(asm_default)}}} \
+%{mcpu=native: %(asm_cpu_native)} \
 %{mcpu=common: -mcom} \
 %{mcpu=cell: -mcell} \
 %{mcpu=power: -mpwr} \
 #define EXTRA_SPECS                                                    \
   { "cpp_default",             CPP_DEFAULT_SPEC },                     \
   { "asm_cpu",                 ASM_CPU_SPEC },                         \
+  { "asm_cpu_native",          ASM_CPU_NATIVE_SPEC },                  \
   { "asm_default",             ASM_DEFAULT_SPEC },                     \
   { "cc1_cpu",                 CC1_CPU_SPEC },                         \
   { "asm_cpu_power5",          ASM_CPU_POWER5_SPEC },                  \
@@ -184,6 +188,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define EXTRA_SPEC_FUNCTIONS \
   { "local_cpu_detect", host_detect_local_cpu },
 #define HAVE_LOCAL_CPU_DETECT
+#define ASM_CPU_NATIVE_SPEC "%:local_cpu_detect(asm)"
+
+#else
+#define ASM_CPU_NATIVE_SPEC "%(asm_default)"
 #endif
 
 #ifndef CC1_CPU_SPEC
@@ -245,6 +253,22 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define TARGET_DFP 0
 #endif
 
+/* Define TARGET_POPCNTD if the target assembler does not support the
+   popcount word and double word instructions.  */
+
+#ifndef HAVE_AS_POPCNTD
+#undef  TARGET_POPCNTD
+#define TARGET_POPCNTD 0
+#endif
+
+/* Define TARGET_LWSYNC_INSTRUCTION if the assembler knows about lwsync.  If
+   not, generate the lwsync code as an integer constant.  */
+#ifdef HAVE_AS_LWSYNC
+#define TARGET_LWSYNC_INSTRUCTION 1
+#else
+#define TARGET_LWSYNC_INSTRUCTION 0
+#endif
+
 /* Define TARGET_TLS_MARKERS if the target assembler does not support
    arg markers for __tls_get_addr calls.  */
 #ifndef HAVE_AS_TLS_MARKERS
@@ -309,6 +333,7 @@ enum processor_type
    PROCESSOR_POWER4,
    PROCESSOR_POWER5,
    PROCESSOR_POWER6,
+   PROCESSOR_POWER7,
    PROCESSOR_CELL
 };
 
@@ -392,9 +417,15 @@ extern struct rs6000_cpu_select rs6000_select[];
 extern const char *rs6000_debug_name;  /* Name for -mdebug-xxxx option */
 extern int rs6000_debug_stack;         /* debug stack applications */
 extern int rs6000_debug_arg;           /* debug argument handling */
+extern int rs6000_debug_reg;           /* debug register handling */
+extern int rs6000_debug_addr;          /* debug memory addressing */
+extern int rs6000_debug_cost;          /* debug rtx_costs */
 
 #define        TARGET_DEBUG_STACK      rs6000_debug_stack
 #define        TARGET_DEBUG_ARG        rs6000_debug_arg
+#define TARGET_DEBUG_REG       rs6000_debug_reg
+#define TARGET_DEBUG_ADDR      rs6000_debug_addr
+#define TARGET_DEBUG_COST      rs6000_debug_cost
 
 extern const char *rs6000_traceback_name; /* Type of traceback table.  */
 
@@ -405,13 +436,65 @@ extern int rs6000_ieeequad;
 extern int rs6000_altivec_abi;
 extern int rs6000_spe_abi;
 extern int rs6000_spe;
-extern int rs6000_isel;
 extern int rs6000_float_gprs;
 extern int rs6000_alignment_flags;
 extern const char *rs6000_sched_insert_nops_str;
 extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 extern int rs6000_xilinx_fpu;
 
+/* Describe which vector unit to use for a given machine mode.  */
+enum rs6000_vector {
+  VECTOR_NONE,                 /* Type is not  a vector or not supported */
+  VECTOR_ALTIVEC,              /* Use altivec for vector processing */
+  VECTOR_VSX,                  /* Use VSX for vector processing */
+  VECTOR_PAIRED,               /* Use paired floating point for vectors */
+  VECTOR_SPE,                  /* Use SPE for vector processing */
+  VECTOR_OTHER                 /* Some other vector unit */
+};
+
+extern enum rs6000_vector rs6000_vector_unit[];
+
+#define VECTOR_UNIT_NONE_P(MODE)                       \
+  (rs6000_vector_unit[(MODE)] == VECTOR_NONE)
+
+#define VECTOR_UNIT_VSX_P(MODE)                                \
+  (rs6000_vector_unit[(MODE)] == VECTOR_VSX)
+
+#define VECTOR_UNIT_ALTIVEC_P(MODE)                    \
+  (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC)
+
+#define VECTOR_UNIT_ALTIVEC_OR_VSX_P(MODE)             \
+  (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC        \
+   || rs6000_vector_unit[(MODE)] == VECTOR_VSX)
+
+/* Describe whether to use VSX loads or Altivec loads.  For now, just use the
+   same unit as the vector unit we are using, but we may want to migrate to
+   using VSX style loads even for types handled by altivec.  */
+extern enum rs6000_vector rs6000_vector_mem[];
+
+#define VECTOR_MEM_NONE_P(MODE)                                \
+  (rs6000_vector_mem[(MODE)] == VECTOR_NONE)
+
+#define VECTOR_MEM_VSX_P(MODE)                         \
+  (rs6000_vector_mem[(MODE)] == VECTOR_VSX)
+
+#define VECTOR_MEM_ALTIVEC_P(MODE)                     \
+  (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC)
+
+#define VECTOR_MEM_ALTIVEC_OR_VSX_P(MODE)              \
+  (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC         \
+   || rs6000_vector_mem[(MODE)] == VECTOR_VSX)
+
+/* Return the alignment of a given vector type, which is set based on the
+   vector unit use.  VSX for instance can load 32 or 64 bit aligned words
+   without problems, while Altivec requires 128-bit aligned vectors.  */
+extern int rs6000_vector_align[];
+
+#define VECTOR_ALIGN(MODE)                                             \
+  ((rs6000_vector_align[(MODE)] != 0)                                  \
+   ? rs6000_vector_align[(MODE)]                                       \
+   : (int)GET_MODE_BITSIZE ((MODE)))
+
 /* Alignment options for fields in structures for sub-targets following
    AIX-like ABI.
    ALIGN_POWER word-aligns FP doubles (default AIX ABI).
@@ -432,11 +515,12 @@ extern int rs6000_xilinx_fpu;
 #define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
 #define TARGET_IEEEQUAD rs6000_ieeequad
 #define TARGET_ALTIVEC_ABI rs6000_altivec_abi
+#define TARGET_LDBRX (TARGET_POPCNTD || rs6000_cpu == PROCESSOR_CELL)
 
 #define TARGET_SPE_ABI 0
 #define TARGET_SPE 0
 #define TARGET_E500 0
-#define TARGET_ISEL rs6000_isel
+#define TARGET_ISEL64 (TARGET_ISEL && TARGET_POWERPC64)
 #define TARGET_FPRS 1
 #define TARGET_E500_SINGLE 0
 #define TARGET_E500_DOUBLE 0
@@ -534,6 +618,7 @@ extern int rs6000_xilinx_fpu;
 #endif
 #define UNITS_PER_FP_WORD 8
 #define UNITS_PER_ALTIVEC_WORD 16
+#define UNITS_PER_VSX_WORD 16
 #define UNITS_PER_SPE_WORD 8
 #define UNITS_PER_PAIRED_WORD 8
 
@@ -598,14 +683,16 @@ extern int rs6000_xilinx_fpu;
 
 /* Width in bits of a pointer.
    See also the macro `Pmode' defined below.  */
-#define POINTER_SIZE (TARGET_32BIT ? 32 : 64)
+extern unsigned rs6000_pointer_size;
+#define POINTER_SIZE rs6000_pointer_size
 
 /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
 #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
 
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
-#define STACK_BOUNDARY \
-  ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define STACK_BOUNDARY \
+  ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI && !TARGET_VSX) \
+    ? 64 : 128)
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
 #define FUNCTION_BOUNDARY 32
@@ -617,10 +704,11 @@ extern int rs6000_xilinx_fpu;
    local store.  TYPE is the data type, and ALIGN is the alignment
    that the object would ordinarily have.  */
 #define LOCAL_ALIGNMENT(TYPE, ALIGN)                           \
-  ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
+  (((TARGET_ALTIVEC || TARGET_VSX)                             \
+    && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 :                        \
     (TARGET_E500_DOUBLE                                                \
-     && TYPE_MODE (TYPE) == DFmode) ? 64 : \
-    ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \
+     && TYPE_MODE (TYPE) == DFmode) ? 64 :                     \
+    ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE            \
      && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \
         && TREE_CODE (TYPE) == VECTOR_TYPE \
         && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) ? 64 : ALIGN)
@@ -678,15 +766,17 @@ extern int rs6000_xilinx_fpu;
 /* 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.  */
-/* Altivec vector memory instructions simply ignore the low bits; SPE
-   vector memory instructions trap on unaligned accesses.  */
+/* Altivec vector memory instructions simply ignore the low bits; SPE vector
+   memory instructions trap on unaligned accesses; VSX memory instructions are
+   aligned to 4 or 8 bytes.  */
 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN)                             \
   (STRICT_ALIGNMENT                                                    \
    || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode       \
        || (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode     \
        || (MODE) == DImode)                                            \
        && (ALIGN) < 32)                                                        \
-   || (VECTOR_MODE_P ((MODE)) && (ALIGN) < GET_MODE_BITSIZE ((MODE))))
+   || (VECTOR_MODE_P ((MODE)) && (((int)(ALIGN)) < VECTOR_ALIGN (MODE))))
+
 \f
 /* Standard register usage.  */
 
@@ -913,16 +1003,49 @@ extern int rs6000_xilinx_fpu;
 /* True if register is an AltiVec register.  */
 #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
 
+/* True if register is a VSX register.  */
+#define VSX_REGNO_P(N) (FP_REGNO_P (N) || ALTIVEC_REGNO_P (N))
+
+/* Alternate name for any vector register supporting floating point, no matter
+   which instruction set(s) are available.  */
+#define VFLOAT_REGNO_P(N) \
+  (ALTIVEC_REGNO_P (N) || (TARGET_VSX && FP_REGNO_P (N)))
+
+/* Alternate name for any vector register supporting integer, no matter which
+   instruction set(s) are available.  */
+#define VINT_REGNO_P(N) ALTIVEC_REGNO_P (N)
+
+/* Alternate name for any vector register supporting logical operations, no
+   matter which instruction set(s) are available.  */
+#define VLOGICAL_REGNO_P(N) VFLOAT_REGNO_P (N)
+
 /* Return number of consecutive hard regs needed starting at reg REGNO
    to hold something of mode MODE.  */
 
-#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs ((REGNO), (MODE))
+#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)]
 
 #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE)    \
   ((TARGET_32BIT && TARGET_POWERPC64                   \
     && (GET_MODE_SIZE (MODE) > 4)  \
     && INT_REGNO_P (REGNO)) ? 1 : 0)
 
+#define VSX_VECTOR_MODE(MODE)          \
+        ((MODE) == V4SFmode            \
+         || (MODE) == V2DFmode)        \
+
+#define VSX_SCALAR_MODE(MODE)          \
+       ((MODE) == DFmode)
+
+#define VSX_MODE(MODE)                 \
+       (VSX_VECTOR_MODE (MODE)         \
+        || VSX_SCALAR_MODE (MODE))
+
+#define VSX_MOVE_MODE(MODE)            \
+       (VSX_VECTOR_MODE (MODE)         \
+        || VSX_SCALAR_MODE (MODE)      \
+        || ALTIVEC_VECTOR_MODE (MODE)  \
+        || (MODE) == TImode)
+
 #define ALTIVEC_VECTOR_MODE(MODE)      \
         ((MODE) == V16QImode           \
          || (MODE) == V8HImode         \
@@ -938,10 +1061,12 @@ extern int rs6000_xilinx_fpu;
 #define PAIRED_VECTOR_MODE(MODE)        \
          ((MODE) == V2SFmode)            
 
-#define UNITS_PER_SIMD_WORD(MODE)                                   \
-       (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD                     \
-        : (TARGET_SPE ? UNITS_PER_SPE_WORD : (TARGET_PAIRED_FLOAT ? \
-        UNITS_PER_PAIRED_WORD : UNITS_PER_WORD)))
+#define UNITS_PER_SIMD_WORD(MODE)                                      \
+       (TARGET_VSX ? UNITS_PER_VSX_WORD                                \
+        : (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD                     \
+        : (TARGET_SPE ? UNITS_PER_SPE_WORD                             \
+        : (TARGET_PAIRED_FLOAT ? UNITS_PER_PAIRED_WORD                 \
+        : UNITS_PER_WORD))))
 
 /* Value is TRUE if hard register REGNO can hold a value of
    machine-mode MODE.  */
@@ -969,6 +1094,10 @@ extern int rs6000_xilinx_fpu;
    ? ALTIVEC_VECTOR_MODE (MODE2)               \
    : ALTIVEC_VECTOR_MODE (MODE2)               \
    ? ALTIVEC_VECTOR_MODE (MODE1)               \
+   : VSX_VECTOR_MODE (MODE1)                   \
+   ? VSX_VECTOR_MODE (MODE2)                   \
+   : VSX_VECTOR_MODE (MODE2)                   \
+   ? VSX_VECTOR_MODE (MODE1)                   \
    : 1)
 
 /* Post-reload, we can't use any new AltiVec registers, as we already
@@ -1054,9 +1183,10 @@ extern int rs6000_xilinx_fpu;
    For any two classes, it is very desirable that there be another
    class that represents their union.  */
 
-/* The RS/6000 has three types of registers, fixed-point, floating-point,
-   and condition registers, plus three special registers, MQ, CTR, and the
-   link register.  AltiVec adds a vector register class.
+/* The RS/6000 has three types of registers, fixed-point, floating-point, and
+   condition registers, plus three special registers, MQ, CTR, and the link
+   register.  AltiVec adds a vector register class.  VSX registers overlap the
+   FPR registers and the Altivec registers.
 
    However, r0 is special in that it cannot be used as a base register.
    So make a class for registers valid as base registers.
@@ -1169,29 +1299,28 @@ enum reg_class
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
 
-#define REGNO_REG_CLASS(REGNO)                 \
- ((REGNO) == 0 ? GENERAL_REGS                  \
-  : (REGNO) < 32 ? BASE_REGS                   \
-  : FP_REGNO_P (REGNO) ? FLOAT_REGS            \
-  : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS     \
-  : (REGNO) == CR0_REGNO ? CR0_REGS            \
-  : CR_REGNO_P (REGNO) ? CR_REGS               \
-  : (REGNO) == MQ_REGNO ? MQ_REGS              \
-  : (REGNO) == LR_REGNO ? LINK_REGS    \
-  : (REGNO) == CTR_REGNO ? CTR_REGS    \
-  : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS  \
-  : (REGNO) == XER_REGNO ? XER_REGS            \
-  : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS      \
-  : (REGNO) == VSCR_REGNO ? VRSAVE_REGS                \
-  : (REGNO) == SPE_ACC_REGNO ? SPE_ACC_REGS    \
-  : (REGNO) == SPEFSCR_REGNO ? SPEFSCR_REGS    \
-  : (REGNO) == FRAME_POINTER_REGNUM ? BASE_REGS        \
-  : NO_REGS)
+extern enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
+
+#if ENABLE_CHECKING
+#define REGNO_REG_CLASS(REGNO)                                                 \
+  (gcc_assert (IN_RANGE ((REGNO), 0, FIRST_PSEUDO_REGISTER-1)),                \
+   rs6000_regno_regclass[(REGNO)])
+
+#else
+#define REGNO_REG_CLASS(REGNO) rs6000_regno_regclass[(REGNO)]
+#endif
+
+/* VSX register classes.  */
+extern enum reg_class rs6000_vector_reg_class[];
 
 /* The class value for index registers, and the one for base regs.  */
 #define INDEX_REG_CLASS GENERAL_REGS
 #define BASE_REG_CLASS BASE_REGS
 
+/* Return whether a given register class can hold VSX objects.  */
+#define VSX_REG_CLASS_P(CLASS)                 \
+  ((CLASS) == VSX_REGS || (CLASS) == FLOAT_REGS || (CLASS) == ALTIVEC_REGS)
+
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
    In general this is just CLASS; but on some machines
@@ -1255,15 +1384,10 @@ enum reg_class
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class 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)                                              \
-  ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
-  : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS                     \
-     && (MODE) == DFmode)                              \
-  ? 1                                                                   \
-  : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+   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, unless we have VSX, where the FP
+   registers can hold 128 bits.  */
+#define CLASS_MAX_NREGS(CLASS, MODE) rs6000_class_max_nregs[(MODE)][(CLASS)]
 
 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid.  */
 
@@ -1341,8 +1465,8 @@ extern enum rs6000_abi rs6000_current_abi;        /* available for use by subtarget */
 #define STARTING_FRAME_OFFSET                                          \
   (FRAME_GROWS_DOWNWARD                                                        \
    ? 0                                                                 \
-   : (RS6000_ALIGN (crtl->outgoing_args_size,          \
-                   TARGET_ALTIVEC ? 16 : 8)                            \
+   : (RS6000_ALIGN (crtl->outgoing_args_size,                          \
+                   (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8)            \
       + RS6000_SAVE_AREA))
 
 /* Offset from the stack pointer register to an item dynamically
@@ -1352,8 +1476,8 @@ extern enum rs6000_abi rs6000_current_abi;        /* available for use by subtarget */
    length of the outgoing arguments.  The default is correct for most
    machines.  See `function.c' for details.  */
 #define STACK_DYNAMIC_OFFSET(FUNDECL)                                  \
-  (RS6000_ALIGN (crtl->outgoing_args_size,                     \
-                TARGET_ALTIVEC ? 16 : 8)                               \
+  (RS6000_ALIGN (crtl->outgoing_args_size,                             \
+                (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8)               \
    + (STACK_POINTER_OFFSET))
 
 /* If we generate an insn to push BYTES bytes,
@@ -1603,7 +1727,7 @@ typedef struct rs6000_args
 #define        EPILOGUE_USES(REGNO)                                    \
   ((reload_completed && (REGNO) == LR_REGNO)                   \
    || (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO)              \
-   || (crtl->calls_eh_return                           \
+   || (crtl->calls_eh_return                                   \
        && TARGET_AIX                                           \
        && (REGNO) == 2))
 
@@ -1892,7 +2016,8 @@ do {                                                              \
 /* Specify the machine mode that pointers have.
    After generation of rtl, the compiler makes no further distinction
    between pointers and any other objects of this machine mode.  */
-#define Pmode (TARGET_32BIT ? SImode : DImode)
+extern unsigned rs6000_pmode;
+#define Pmode ((enum machine_mode)rs6000_pmode)
 
 /* Supply definition of STACK_SIZE_MODE for allocate_dynamic_stack_space.  */
 #define STACK_SIZE_MODE (TARGET_32BIT ? SImode : DImode)
@@ -2233,7 +2358,24 @@ extern char rs6000_reg_names[][8];       /* register names (0 vs. %r0).  */
   /* no additional names for: mq, lr, ctr, ap */               \
   {"cr0",  68}, {"cr1",  69}, {"cr2",  70}, {"cr3",  71},      \
   {"cr4",  72}, {"cr5",  73}, {"cr6",  74}, {"cr7",  75},      \
-  {"cc",   68}, {"sp",    1}, {"toc",   2} }
+  {"cc",   68}, {"sp",    1}, {"toc",   2},                    \
+  /* VSX registers overlaid on top of FR, Altivec registers */ \
+  {"vs0",  32}, {"vs1",  33}, {"vs2",  34}, {"vs3",  35},      \
+  {"vs4",  36}, {"vs5",  37}, {"vs6",  38}, {"vs7",  39},      \
+  {"vs8",  40}, {"vs9",  41}, {"vs10", 42}, {"vs11", 43},      \
+  {"vs12", 44}, {"vs13", 45}, {"vs14", 46}, {"vs15", 47},      \
+  {"vs16", 48}, {"vs17", 49}, {"vs18", 50}, {"vs19", 51},      \
+  {"vs20", 52}, {"vs21", 53}, {"vs22", 54}, {"vs23", 55},      \
+  {"vs24", 56}, {"vs25", 57}, {"vs26", 58}, {"vs27", 59},      \
+  {"vs28", 60}, {"vs29", 61}, {"vs30", 62}, {"vs31", 63},      \
+  {"vs32", 77}, {"vs33", 78}, {"vs34", 79}, {"vs35", 80},       \
+  {"vs36", 81}, {"vs37", 82}, {"vs38", 83}, {"vs39", 84},       \
+  {"vs40", 85}, {"vs41", 86}, {"vs42", 87}, {"vs43", 88},       \
+  {"vs44", 89}, {"vs45", 90}, {"vs46", 91}, {"vs47", 92},       \
+  {"vs48", 93}, {"vs49", 94}, {"vs50", 95}, {"vs51", 96},       \
+  {"vs52", 97}, {"vs53", 98}, {"vs54", 99}, {"vs55", 100},     \
+  {"vs56", 101},{"vs57", 102},{"vs58", 103},{"vs59", 104},      \
+  {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108} }
 
 /* Text to write out after a CALL that may be replaced by glue code by
    the loader.  This depends on the AIX version.  */
index cc6478ec847bd41b8e49c9dbcf2e54a342d40731..9a4079c4fbc7ab8f52160bd4dd81dd0ba475f65d 100644 (file)
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in rs6000.h.
 
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,cell"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,power7,cell"
   (const (symbol_ref "rs6000_cpu_attr")))
 
 
 ; DImode bits
 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
 
+;; ISEL/ISEL64 target selection
+(define_mode_attr sel [(SI "") (DI "64")])
+
+;; Suffix for reload patterns
+(define_mode_attr ptrsize [(SI "32bit")
+                          (DI "64bit")])
+
+(define_mode_attr tptrsize [(SI "TARGET_32BIT")
+                           (DI "TARGET_64BIT")])
+
+(define_mode_attr mptrsize [(SI "si")
+                           (DI "di")])
+
 \f
 ;; Start with fixed-point load and store insns.  Here we put only the more
 ;; complex forms.  Basic data transfer is done later.
   "@
    {andil.|andi.} %2,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    {andil.|andi.} %0,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    {andil.|andi.} %2,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    {andil.|andi.} %0,%1,0xff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    {andil.|andi.} %2,%1,0xffff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    {andil.|andi.} %0,%1,0xffff
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    nor. %2,%1,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    nor. %0,%1,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "TARGET_POPCNTB"
   "popcntb %0,%1")
 
+(define_insn "popcntwsi2"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+       (popcount:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
+  "TARGET_POPCNTD"
+  "popcntw %0,%1")
+
+(define_insn "popcntddi2"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+       (popcount:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
+  "TARGET_POPCNTD && TARGET_POWERPC64"
+  "popcntd %0,%1")
+
 (define_expand "popcount<mode>2"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
        (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
-  "TARGET_POPCNTB"
+  "TARGET_POPCNTB || TARGET_POPCNTD"
   {
     rs6000_emit_popcount (operands[0], operands[1]);
     DONE;
    {rlinm|rlwinm} %0,%1,0,%m2,%M2
    {andil.|andi.} %0,%1,%b2
    {andiu.|andis.} %0,%1,%u2"
-  [(set_attr "type" "*,*,compare,compare")])
+  [(set_attr "type" "*,*,fast_compare,fast_compare")])
 
 (define_insn "andsi3_nomc"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
+                    compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,8,8,8,8")])
 
 (define_insn "*andsi3_internal3_mc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
+                    compare,compare,compare")
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
 (define_split
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
+                    compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,8,8,8,8")])
 
 (define_insn "*andsi3_internal5_mc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
+  [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
+                    compare,compare,compare")
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
 (define_split
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "fres %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn ""
+(define_insn "*fmaddsf4_powerpc"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                          (match_operand:SF 2 "gpc_reg_operand" "f"))
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fmaddsf4_power"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                          (match_operand:SF 2 "gpc_reg_operand" "f"))
   "{fma|fmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fmsubsf4_powerpc"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                           (match_operand:SF 2 "gpc_reg_operand" "f"))
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fmsubsf4_power"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                           (match_operand:SF 2 "gpc_reg_operand" "f"))
   "{fms|fmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_powerpc_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                  (match_operand:SF 2 "gpc_reg_operand" "f"))
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_powerpc_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
                           (match_operand:SF 2 "gpc_reg_operand" "f"))
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_power_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                  (match_operand:SF 2 "gpc_reg_operand" "f"))
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmaddsf4_power_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
                           (match_operand:SF 2 "gpc_reg_operand" "f"))
   "{fnma|fnmadd} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_powerpc_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                   (match_operand:SF 2 "gpc_reg_operand" "f"))
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_powerpc_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
                  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_maddsub_s")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_power_1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
                                   (match_operand:SF 2 "gpc_reg_operand" "f"))
   "{fnms|fnmsub} %0,%1,%2,%3"
   [(set_attr "type" "dmul")])
 
-(define_insn ""
+(define_insn "*fnmsubsf4_power_2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
        (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
                  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
   DONE;
 }")
 
-(define_expand "movsicc"
-   [(set (match_operand:SI 0 "gpc_reg_operand" "")
-        (if_then_else:SI (match_operand 1 "comparison_operator" "")
-                         (match_operand:SI 2 "gpc_reg_operand" "")
-                         (match_operand:SI 3 "gpc_reg_operand" "")))]
-  "TARGET_ISEL"
+(define_expand "mov<mode>cc"
+   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
+        (if_then_else:GPR (match_operand 1 "comparison_operator" "")
+                          (match_operand:GPR 2 "gpc_reg_operand" "")
+                          (match_operand:GPR 3 "gpc_reg_operand" "")))]
+  "TARGET_ISEL<sel>"
   "
 {
   if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
 ;; leave out the mode in operand 4 and use one pattern, but reload can
 ;; change the mode underneath our feet and then gets confused trying
 ;; to reload the value.
-(define_insn "isel_signed"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (if_then_else:SI
+(define_insn "isel_signed_<mode>"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+       (if_then_else:GPR
         (match_operator 1 "comparison_operator"
                         [(match_operand:CC 4 "cc_reg_operand" "y")
                          (const_int 0)])
-        (match_operand:SI 2 "gpc_reg_operand" "b")
-        (match_operand:SI 3 "gpc_reg_operand" "b")))]
-  "TARGET_ISEL"
+        (match_operand:GPR 2 "gpc_reg_operand" "b")
+        (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+  "TARGET_ISEL<sel>"
   "*
 { return output_isel (operands); }"
   [(set_attr "length" "4")])
 
-(define_insn "isel_unsigned"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (if_then_else:SI
+(define_insn "isel_unsigned_<mode>"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+       (if_then_else:GPR
         (match_operator 1 "comparison_operator"
                         [(match_operand:CCUNS 4 "cc_reg_operand" "y")
                          (const_int 0)])
-        (match_operand:SI 2 "gpc_reg_operand" "b")
-        (match_operand:SI 3 "gpc_reg_operand" "b")))]
-  "TARGET_ISEL"
+        (match_operand:GPR 2 "gpc_reg_operand" "b")
+        (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+  "TARGET_ISEL<sel>"
   "*
 { return output_isel (operands); }"
   [(set_attr "length" "4")])
  "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
  "")
 
+(define_expand "fixuns_truncdfsi2"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+       (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
+  "")
+
 ; 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,
    andi. %0,%1,%b2
    andis. %0,%1,%u2
    #"
-  [(set_attr "type" "*,*,*,compare,compare,*")
+  [(set_attr "type" "*,*,*,fast_compare,fast_compare,*")
    (set_attr "length" "4,4,4,4,4,8")])
 
 (define_insn "anddi3_nomc"
    #
    #
    #"
-  [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
+                    fast_compare,compare,compare,compare,compare,compare,\
+                    compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
    #
    #
    #"
-  [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
+  [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
+                    fast_compare,compare,compare,compare,compare,compare,\
+                    compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
 (define_split
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %3,%2,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %0,%2,%1
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %3,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
   "@
    %q4. %0,%1,%2
    #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "fast_compare,compare")
    (set_attr "length" "4,8")])
 
 (define_split
        (compare:CC (match_dup 0)
                    (const_int 0)))]
   "")
+
+(define_expand "smindi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
+  DONE;
+}")
+
+(define_expand "smaxdi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
+  DONE;
+}")
+
+(define_expand "umindi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], UMIN, operands[1], operands[2]);
+  DONE;
+}")
+
+(define_expand "umaxdi3"
+  [(match_operand:DI 0 "gpc_reg_operand" "")
+   (match_operand:DI 1 "gpc_reg_operand" "")
+   (match_operand:DI 2 "gpc_reg_operand" "")]
+  "TARGET_ISEL64"
+  "
+{
+  rs6000_emit_minmax (operands[0], UMAX, operands[1], operands[2]);
+  DONE;
+}")
+
 \f
 ;; Now define ways of moving data around.
 
index 45e1c8f5a56b7d75ebb064a5c0e84a885331f22b..00bd1b0e7a0d084b6212f38ae6ef031ac7d26dd7 100644 (file)
@@ -111,24 +111,24 @@ mhard-float
 Target Report RejectNegative InverseMask(SOFT_FLOAT, HARD_FLOAT)
 Use hardware floating point
 
-mno-update
-Target Report RejectNegative Mask(NO_UPDATE)
-Do not generate load/store with update instructions
+mpopcntd
+Target Report Mask(POPCNTD)
+Use PowerPC V2.06 popcntd instruction
+
+mvsx
+Target Report Mask(VSX)
+Use vector/scalar (VSX) instructions
 
 mupdate
-Target Report RejectNegative InverseMask(NO_UPDATE, UPDATE)
+Target Report Var(TARGET_UPDATE) Init(1)
 Generate load/store with update instructions
 
 mavoid-indexed-addresses
 Target Report Var(TARGET_AVOID_XFORM) Init(-1)
 Avoid generation of indexed load/store instructions when possible
 
-mno-fused-madd
-Target Report RejectNegative Mask(NO_FUSED_MADD)
-Do not generate fused multiply/add instructions
-
 mfused-madd
-Target Report RejectNegative InverseMask(NO_FUSED_MADD, FUSED_MADD)
+Target Report Var(TARGET_FUSED_MADD) Init(1)
 Generate fused multiply/add instructions
 
 mtls-markers
@@ -198,7 +198,7 @@ Target RejectNegative Joined
 -mvrsave=yes/no        Deprecated option.  Use -mvrsave/-mno-vrsave instead
 
 misel
-Target
+Target Report Mask(ISEL)
 Generate isel instructions
 
 misel=
index 5368bace302a6979e682ac285ae099307a7d9df1..917f817c2bf1fb3bef6b4925e8df22d92de80fd6 100644 (file)
@@ -1,5 +1,5 @@
 ;; e500 SPE description
-;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
 ;; Free Software Foundation, Inc.
 ;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
 
@@ -99,7 +99,7 @@
 
 ;; Floating point conversion instructions.
 
-(define_insn "fixuns_truncdfsi2"
+(define_insn "spe_fixuns_truncdfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "r")))]
   "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
index 9d1ef9b580f1d9d025dffb67f0c8367935aa7c34..f6cc91d3d56add23b3c0bb4faf73057982cb2e48 100644 (file)
   if (TARGET_NO_LWSYNC)
     return "sync";
   else
-    return ".long 0x7c2004ac";
+    return (TARGET_LWSYNC_INSTRUCTION) ? "lwsync" : ".long 0x7c2004ac";
 }
   [(set_attr "type" "sync")])
 
index 611c0d299c8f37e8452bf36795e1c633d382012a..4d28e375363939dc8a888cafa475e8119221cca4 100644 (file)
@@ -125,9 +125,9 @@ do {                                                                        \
   else if (!strcmp (rs6000_abi_name, "i960-old"))                      \
     {                                                                  \
       rs6000_current_abi = ABI_V4;                                     \
-      target_flags |= (MASK_LITTLE_ENDIAN | MASK_EABI                  \
-                      | MASK_NO_BITFIELD_WORD);                        \
+      target_flags |= (MASK_LITTLE_ENDIAN | MASK_EABI);                        \
       target_flags &= ~MASK_STRICT_ALIGN;                              \
+      TARGET_NO_BITFIELD_WORD = 1;                                     \
     }                                                                  \
   else                                                                 \
     {                                                                  \
index 1ead31d4c0155e2057b97a2bbb8c64426458a298..428417ec4a8fc33a097d5dc7cbe199046832b214 100644 (file)
@@ -1,6 +1,6 @@
 ; SYSV4 options for PPC port.
 ;
-; Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
+; Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 ; Contributed by Aldy Hernandez <aldy@quesejoda.com>.
 ;
 ; This file is part of GCC.
@@ -32,7 +32,7 @@ Target RejectNegative Joined
 Specify bit size of immediate TLS offsets
 
 mbit-align
-Target Report Mask(NO_BITFIELD_TYPE)
+Target Report Var(TARGET_NO_BITFIELD_TYPE)
 Align to the base type of the bit-field
 
 mstrict-align
@@ -87,11 +87,11 @@ Target Report Mask(EABI)
 Use EABI
 
 mbit-word
-Target Report Mask(NO_BITFIELD_WORD)
+Target Report Var(TARGET_NO_BITFIELD_WORD)
 Allow bit-fields to cross word boundaries
 
 mregnames
-Target Mask(REGNAMES)
+Target Var(TARGET_REGNAMES)
 Use alternate register names
 
 ;; This option does nothing and only exists because the compiler
index 1a838c54bc35a4392467e0375d9ca427c12889f3..695f5799f11afbb78cbf009bfe713a5c23e48588 100644 (file)
@@ -36,3 +36,30 @@ rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
 
 # The rs6000 backend doesn't cause warnings in these files.
 insn-conditions.o-warn =
+
+MD_INCLUDES = $(srcdir)/config/rs6000/rios1.md \
+       $(srcdir)/config/rs6000/rios2.md \
+       $(srcdir)/config/rs6000/rs64.md \
+       $(srcdir)/config/rs6000/mpc.md \
+       $(srcdir)/config/rs6000/40x.md \
+       $(srcdir)/config/rs6000/440.md \
+       $(srcdir)/config/rs6000/603.md \
+       $(srcdir)/config/rs6000/6xx.md \
+       $(srcdir)/config/rs6000/7xx.md \
+       $(srcdir)/config/rs6000/7450.md \
+       $(srcdir)/config/rs6000/8540.md \
+       $(srcdir)/config/rs6000/e300c2c3.md \
+       $(srcdir)/config/rs6000/e500mc.md \
+       $(srcdir)/config/rs6000/power4.md \
+       $(srcdir)/config/rs6000/power5.md \
+       $(srcdir)/config/rs6000/power6.md \
+       $(srcdir)/config/rs6000/cell.md \
+       $(srcdir)/config/rs6000/xfpu.md \
+       $(srcdir)/config/rs6000/predicates.md \
+       $(srcdir)/config/rs6000/constraints.md \
+       $(srcdir)/config/rs6000/darwin.md \
+       $(srcdir)/config/rs6000/sync.md \
+       $(srcdir)/config/rs6000/altivec.md \
+       $(srcdir)/config/rs6000/spe.md \
+       $(srcdir)/config/rs6000/dfp.md \
+       $(srcdir)/config/rs6000/paired.md
index 8713f15ebd523dec21aa543bdf2cc3fde25a587f..8fc162dd2ef649ea46c94d1bee0b294a9b878cf3 100755 (executable)
@@ -23234,7 +23234,7 @@ if test "${gcc_cv_as_powerpc_mfpgpr+set}" = set; then
 else
   gcc_cv_as_powerpc_mfpgpr=no
     if test $in_tree_gas = yes; then
-    if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0`
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
   then gcc_cv_as_powerpc_mfpgpr=yes
 fi
   elif test x$gcc_cv_as != x; then
@@ -23330,7 +23330,7 @@ if test "${gcc_cv_as_powerpc_cmpb+set}" = set; then
 else
   gcc_cv_as_powerpc_cmpb=no
     if test $in_tree_gas = yes; then
-    if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0`
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
   then gcc_cv_as_powerpc_cmpb=yes
 fi
   elif test x$gcc_cv_as != x; then
@@ -23376,7 +23376,7 @@ if test "${gcc_cv_as_powerpc_dfp+set}" = set; then
 else
   gcc_cv_as_powerpc_dfp=no
     if test $in_tree_gas = yes; then
-    if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0`
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
   then gcc_cv_as_powerpc_dfp=yes
 fi
   elif test x$gcc_cv_as != x; then
@@ -23422,7 +23422,7 @@ if test "${gcc_cv_as_powerpc_vsx+set}" = set; then
 else
   gcc_cv_as_powerpc_vsx=no
     if test $in_tree_gas = yes; then
-    if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0`
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
   then gcc_cv_as_powerpc_vsx=yes
 fi
   elif test x$gcc_cv_as != x; then
@@ -23450,6 +23450,96 @@ cat >>confdefs.h <<\_ACEOF
 #define HAVE_AS_VSX 1
 _ACEOF
 
+fi
+
+    case $target in
+      *-*-aix*) conftest_s='   .machine "pwr7"
+       .csect .text[PR]
+       popcntd 3,3';;
+      *) conftest_s='  .machine power7
+       .text
+       popcntd 3,3';;
+    esac
+
+    echo "$as_me:$LINENO: checking assembler for popcntd support" >&5
+echo $ECHO_N "checking assembler for popcntd support... $ECHO_C" >&6
+if test "${gcc_cv_as_powerpc_popcntd+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  gcc_cv_as_powerpc_popcntd=no
+    if test $in_tree_gas = yes; then
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
+  then gcc_cv_as_powerpc_popcntd=yes
+fi
+  elif test x$gcc_cv_as != x; then
+    echo "$conftest_s" > conftest.s
+    if { ac_try='$gcc_cv_as -a32 -o conftest.o conftest.s >&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+    then
+       gcc_cv_as_powerpc_popcntd=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_powerpc_popcntd" >&5
+echo "${ECHO_T}$gcc_cv_as_powerpc_popcntd" >&6
+if test $gcc_cv_as_powerpc_popcntd = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_POPCNTD 1
+_ACEOF
+
+fi
+
+    case $target in
+      *-*-aix*) conftest_s='   .csect .text[PR]
+       lwsync';;
+      *) conftest_s='  .text
+       lwsync';;
+    esac
+
+    echo "$as_me:$LINENO: checking assembler for lwsync support" >&5
+echo $ECHO_N "checking assembler for lwsync support... $ECHO_C" >&6
+if test "${gcc_cv_as_powerpc_lwsync+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  gcc_cv_as_powerpc_lwsync=no
+    if test $in_tree_gas = yes; then
+    if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2`
+  then gcc_cv_as_powerpc_lwsync=yes
+fi
+  elif test x$gcc_cv_as != x; then
+    echo "$conftest_s" > conftest.s
+    if { ac_try='$gcc_cv_as -a32 -o conftest.o conftest.s >&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+    then
+       gcc_cv_as_powerpc_lwsync=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_powerpc_lwsync" >&5
+echo "${ECHO_T}$gcc_cv_as_powerpc_lwsync" >&6
+if test $gcc_cv_as_powerpc_lwsync = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_LWSYNC 1
+_ACEOF
+
 fi
 
     echo "$as_me:$LINENO: checking assembler for .gnu_attribute support" >&5
index f637a11a50a385defa360de3291a7853ee51eabf..341571ccdf69d04caf0aafa6b43df9ee5cfd6ad1 100644 (file)
@@ -3125,7 +3125,7 @@ foo:      nop
     esac
 
     gcc_GAS_CHECK_FEATURE([move fp gpr support],
-      gcc_cv_as_powerpc_mfpgpr, [9,99,0],,
+      gcc_cv_as_powerpc_mfpgpr, [2,19,2],,
       [$conftest_s],,
       [AC_DEFINE(HAVE_AS_MFPGPR, 1,
          [Define if your assembler supports mffgpr and mftgpr.])])
@@ -3159,7 +3159,7 @@ LCF0:
     esac
 
     gcc_GAS_CHECK_FEATURE([compare bytes support],
-      gcc_cv_as_powerpc_cmpb, [9,99,0], -a32,
+      gcc_cv_as_powerpc_cmpb, [2,19,2], -a32,
       [$conftest_s],,
       [AC_DEFINE(HAVE_AS_CMPB, 1,
          [Define if your assembler supports cmpb.])])
@@ -3174,7 +3174,7 @@ LCF0:
     esac
 
     gcc_GAS_CHECK_FEATURE([decimal float support],
-      gcc_cv_as_powerpc_dfp, [9,99,0], -a32,
+      gcc_cv_as_powerpc_dfp, [2,19,2], -a32,
       [$conftest_s],,
       [AC_DEFINE(HAVE_AS_DFP, 1,
          [Define if your assembler supports DFP instructions.])])
@@ -3189,11 +3189,39 @@ LCF0:
     esac
 
     gcc_GAS_CHECK_FEATURE([vector-scalar support],
-      gcc_cv_as_powerpc_vsx, [9,99,0], -a32,
+      gcc_cv_as_powerpc_vsx, [2,19,2], -a32,
       [$conftest_s],,
       [AC_DEFINE(HAVE_AS_VSX, 1,
          [Define if your assembler supports VSX instructions.])])
 
+    case $target in
+      *-*-aix*) conftest_s='   .machine "pwr7"
+       .csect .text[[PR]]
+       popcntd 3,3';;
+      *) conftest_s='  .machine power7
+       .text
+       popcntd 3,3';;
+    esac
+
+    gcc_GAS_CHECK_FEATURE([popcntd support],
+      gcc_cv_as_powerpc_popcntd, [2,19,2], -a32,
+      [$conftest_s],,
+      [AC_DEFINE(HAVE_AS_POPCNTD, 1,
+         [Define if your assembler supports POPCNTD instructions.])])
+
+    case $target in
+      *-*-aix*) conftest_s='   .csect .text[[PR]]
+       lwsync';;
+      *) conftest_s='  .text
+       lwsync';;
+    esac
+
+    gcc_GAS_CHECK_FEATURE([lwsync support],
+      gcc_cv_as_powerpc_lwsync, [2,19,2], -a32,
+      [$conftest_s],,
+      [AC_DEFINE(HAVE_AS_LWSYNC, 1,
+         [Define if your assembler supports LWSYNC instructions.])])
+
     gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
       gcc_cv_as_powerpc_gnu_attribute, [2,18,0],,
       [.gnu_attribute 4,1],,