OSDN Git Service

ChangeLog
authortsmigiel <tsmigiel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Nov 2006 01:35:42 +0000 (01:35 +0000)
committertsmigiel <tsmigiel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Nov 2006 01:35:42 +0000 (01:35 +0000)
* configure.in (skipdirs) : Don't build target-libiberty for SPU.
* configure : Rebuilt.

gcc/ChangeLog

* config.gcc : Add target for SPU.
* config/spu/constraints.md : New file.
* config/spu/crt0.c : New file.
* config/spu/crtend.c : New file.
* config/spu/crti.asm : New file.
* config/spu/crtn.asm : New file.
* config/spu/float_unsdidf.c : New file.
* config/spu/float_unssidf.c : New file.
* config/spu/predicates.md : New file.
* config/spu/spu-builtins.def : New file.
* config/spu/spu-builtins.h : New file.
* config/spu/spu-builtins.md : New file.
* config/spu/spu-c.c : New file.
* config/spu/spu-elf.h : New file.
* config/spu/spu-modes.def : New file.
* config/spu/spu-protos.h : New file.
* config/spu/spu.c : New file.
* config/spu/spu.h : New file.
* config/spu/spu.md : New file.
* config/spu/spu.opt : New file.
* config/spu/spu_internals.h : New file.
* config/spu/spu_intrinsics.h : New file.
* config/spu/spu_mfcio.h : New file.
* config/spu/t-spu-elf : New file.
* config/spu/vec_types.h : New file.
* config/spu/vmx2spu.h : New file.
* doc/contrib.texi : Document SPU contributor.
* doc/extend.texi : Document SPU extensions.
* doc/invoke.texi : Document SPU options.
* doc/md.texi : Document SPU constraints.

libcpp/ChangeLog

* configure.ac (need_64bit_hwint): Need 64bit hwint for SPU.
* configure : Rebuilt.

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

37 files changed:
ChangeLog
configure
configure.in
gcc/ChangeLog
gcc/config.gcc
gcc/config/spu/constraints.md [new file with mode: 0644]
gcc/config/spu/crt0.c [new file with mode: 0644]
gcc/config/spu/crtend.c [new file with mode: 0644]
gcc/config/spu/crti.asm [new file with mode: 0644]
gcc/config/spu/crtn.asm [new file with mode: 0644]
gcc/config/spu/float_unsdidf.c [new file with mode: 0644]
gcc/config/spu/float_unssidf.c [new file with mode: 0644]
gcc/config/spu/predicates.md [new file with mode: 0644]
gcc/config/spu/spu-builtins.def [new file with mode: 0644]
gcc/config/spu/spu-builtins.h [new file with mode: 0644]
gcc/config/spu/spu-builtins.md [new file with mode: 0644]
gcc/config/spu/spu-c.c [new file with mode: 0644]
gcc/config/spu/spu-elf.h [new file with mode: 0644]
gcc/config/spu/spu-modes.def [new file with mode: 0644]
gcc/config/spu/spu-protos.h [new file with mode: 0644]
gcc/config/spu/spu.c [new file with mode: 0644]
gcc/config/spu/spu.h [new file with mode: 0644]
gcc/config/spu/spu.md [new file with mode: 0644]
gcc/config/spu/spu.opt [new file with mode: 0644]
gcc/config/spu/spu_internals.h [new file with mode: 0644]
gcc/config/spu/spu_intrinsics.h [new file with mode: 0644]
gcc/config/spu/spu_mfcio.h [new file with mode: 0644]
gcc/config/spu/t-spu-elf [new file with mode: 0644]
gcc/config/spu/vec_types.h [new file with mode: 0644]
gcc/config/spu/vmx2spu.h [new file with mode: 0644]
gcc/doc/contrib.texi
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/doc/md.texi
libcpp/ChangeLog
libcpp/configure
libcpp/configure.ac

index 0ad605b..3e01240 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2006-11-20  Trevor Smigiel <trevor_smigiel@playstation.sony.com>
 
 2006-11-20  Trevor Smigiel <trevor_smigiel@playstation.sony.com>
 
+       * configure.in (skipdirs) : Don't build target-libiberty for SPU.
+       * configure : Rebuilt.
+
+2006-11-20  Trevor Smigiel <trevor_smigiel@playstation.sony.com>
+
        * MAINTAINERS (Write After Approval): Add myself.
 
 2006-11-20  Andrea Ornstein  <andrea.ornstein@st.com>
        * MAINTAINERS (Write After Approval): Add myself.
 
 2006-11-20  Andrea Ornstein  <andrea.ornstein@st.com>
index c8b5968..175c280 100755 (executable)
--- a/configure
+++ b/configure
@@ -1598,6 +1598,9 @@ case "${target}" in
     ;;
   sparc-*-solaris* | sparc64-*-solaris* | sparcv9-*-solaris*)
     ;;
     ;;
   sparc-*-solaris* | sparc64-*-solaris* | sparcv9-*-solaris*)
     ;;
+  spu-*-*)
+    skipdirs="target-libiberty"
+    ;;
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;
index 1f5e3bd..3ae50e0 100644 (file)
@@ -774,6 +774,9 @@ case "${target}" in
     ;;
   sparc-*-solaris* | sparc64-*-solaris* | sparcv9-*-solaris*)
     ;;
     ;;
   sparc-*-solaris* | sparc64-*-solaris* | sparcv9-*-solaris*)
     ;;
+  spu-*-*)
+    skipdirs="target-libiberty"
+    ;;
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;
index 7f99e22..fbeb695 100644 (file)
@@ -1,3 +1,42 @@
+2006-11-20  Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
+       Russell Olsen <Russell_Olsen@playstation.sony.com>
+       Dmitri Makarov <Dmitri_Makarov@playstation.sony.com>
+       Yukishige Shibata <shibata@rd.scei.sony.co.jp>
+       Nobuhisa Fujinami <fnami@rd.scei.sony.co.jp>
+       Takeaki Fukuoka <fukuoka@rd.scei.sony.co.jp>
+       Andrew Pinski <Andrew_Pinski@playstation.sony.com>
+
+       * config.gcc : Add target for SPU.
+       * config/spu/constraints.md : New file.
+       * config/spu/crt0.c : New file.
+       * config/spu/crtend.c : New file.
+       * config/spu/crti.asm : New file.
+       * config/spu/crtn.asm : New file.
+       * config/spu/float_unsdidf.c : New file.
+       * config/spu/float_unssidf.c : New file.
+       * config/spu/predicates.md : New file.
+       * config/spu/spu-builtins.def : New file.
+       * config/spu/spu-builtins.h : New file.
+       * config/spu/spu-builtins.md : New file.
+       * config/spu/spu-c.c : New file.
+       * config/spu/spu-elf.h : New file.
+       * config/spu/spu-modes.def : New file.
+       * config/spu/spu-protos.h : New file.
+       * config/spu/spu.c : New file.
+       * config/spu/spu.h : New file.
+       * config/spu/spu.md : New file.
+       * config/spu/spu.opt : New file.
+       * config/spu/spu_internals.h : New file.
+       * config/spu/spu_intrinsics.h : New file.
+       * config/spu/spu_mfcio.h : New file.
+       * config/spu/t-spu-elf : New file.
+       * config/spu/vec_types.h : New file.
+       * config/spu/vmx2spu.h : New file.
+       * doc/contrib.texi : Document SPU contributor.
+       * doc/extend.texi : Document SPU extensions.
+       * doc/invoke.texi : Document SPU options.
+       * doc/md.texi : Document SPU constraints.
+
 2006-11-21  Zdenek Dvorak <dvorakz@suse.cz>
 
        * cfgloopmanip.c (add_loop, duplicate_loop): Do not set level
 2006-11-21  Zdenek Dvorak <dvorakz@suse.cz>
 
        * cfgloopmanip.c (add_loop, duplicate_loop): Do not set level
index 62f6212..ebabf9e 100644 (file)
@@ -321,6 +321,10 @@ sparc64*-*-*)
 sparc*-*-*)
        cpu_type=sparc
        ;;
 sparc*-*-*)
        cpu_type=sparc
        ;;
+spu*-*-*)
+       cpu_type=spu
+       need_64bit_hwint=yes
+       ;;
 s390*-*-*)
        cpu_type=s390
        need_64bit_hwint=yes
 s390*-*-*)
        cpu_type=s390
        need_64bit_hwint=yes
@@ -2326,6 +2330,14 @@ sparc64-*-netbsd*)
        extra_options="${extra_options} sparc/long-double-switch.opt"
        tmake_file="${tmake_file} sparc/t-netbsd64"
        ;;
        extra_options="${extra_options} sparc/long-double-switch.opt"
        tmake_file="${tmake_file} sparc/t-netbsd64"
        ;;
+spu-*-elf*)
+       tm_file="dbxelf.h elfos.h spu/spu-elf.h spu/spu.h"
+       tmake_file="spu/t-spu-elf"
+       extra_headers="spu_intrinsics.h spu_internals.h vmx2spu.h spu_mfcio.h vec_types.h"
+       extra_modes=spu/spu-modes.def
+       c_target_objs="${c_target_objs} spu-c.o"
+       cxx_target_objs="${cxx_target_objs} spu-c.o"
+       ;;
 strongarm-*-elf*)
        tm_file="arm/strongarm-elf.h dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
        tmake_file="arm/t-arm arm/t-strongarm-elf"
 strongarm-*-elf*)
        tm_file="arm/strongarm-elf.h dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
        tmake_file="arm/t-arm arm/t-strongarm-elf"
diff --git a/gcc/config/spu/constraints.md b/gcc/config/spu/constraints.md
new file mode 100644 (file)
index 0000000..6c4fb08
--- /dev/null
@@ -0,0 +1,150 @@
+;; Constraint definitions for SPU
+;; Copyright (C) 2006 Free Software Foundation, Inc.
+;;
+;; This file is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 2 of the License, or (at your option) 
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file; see the file COPYING.  If not, write to the Free
+;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+\f
+;; GCC standard constraints:  g, i, m, n, o, p, r, s, E-H, I-P, V, X
+;; unused for SPU:  E-H, L, Q, d, e, h, j-l, q, t-z
+
+;; For most immediate constraints we have 3 variations to deal with the
+;; fact const_int has no mode.  One variation treats const_int as 32 bit,
+;; another treats it as 64 bit, and the third sign extends it to 128 bit.
+
+(define_constraint "A"
+  "An immediate which can be loaded with the il/ila/ilh/ilhu instructions.  const_int is treated as a 32 bit value."
+  (ior (and (match_code "const_int,const_double,const_vector")
+           (match_test "immediate_load_p (op, SImode)"))
+       (and (match_test "!TARGET_LARGE_MEM && !flag_pic")
+           (ior (match_code "symbol_ref,label_ref")
+                (and (match_code "const")
+                     (match_test "legitimate_const (op, 0)"))))))
+
+(define_constraint "B"
+  "An immediate for arithmetic instructions (e.g., ai, ceqi).  const_int is treated as a 32 bit value."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "arith_immediate_p (op, SImode, -0x200, 0x1ff)")))
+
+(define_constraint "C"
+  "An immediate for and/xor/or instructions.  const_int is treated as a 32 bit value."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "logical_immediate_p (op, SImode)")))
+
+(define_constraint "D"
+  "An immediate for iohl instruction.  const_int is treated as a 32 bit value."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "iohl_immediate_p (op, SImode)")))
+
+(define_constraint "U"
+  "An immediate which can be loaded with the il/ila/ilh/ilhu instructions.  const_int is sign extended to 128 bit."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "immediate_load_p (op, TImode)")))
+
+(define_constraint "W"
+  "An immediate for shift and rotate instructions.  const_int is treated as a 32 bit value."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "arith_immediate_p (op, SImode, -0x40, 0x3f)")))
+
+(define_constraint "Y"
+  "An immediate for and/xor/or instructions.  const_int is sign extended as a 128 bit."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "logical_immediate_p (op, TImode)")))
+
+(define_constraint "Z"
+  "An immediate for iohl instruction.  const_int is sign extended to 128 bit."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "iohl_immediate_p (op, TImode)")))
+
+(define_constraint "a"
+  "An immediate which can be loaded with the il/ila/ilh/ilhu instructions.  const_int is treated as a 64 bit value."
+  (and (match_code "const_int")
+       (match_test "immediate_load_p (op, DImode)")))
+
+(define_constraint "c"
+  "An immediate for and/xor/or instructions.  const_int is treated as a 64 bit value."
+  (and (match_code "const_int")
+       (match_test "logical_immediate_p (op, DImode)")))
+
+(define_constraint "d"
+  "An immediate for iohl instruction.  const_int is treated as a 64 bit value."
+  (and (match_code "const_int")
+       (match_test "iohl_immediate_p (op, DImode)")))
+
+(define_constraint "f"
+  "An immediate which can be loaded with fsmbi."
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "fsmbi_const_p (op)")))
+\f
+;; Integer constraints
+
+(define_constraint "I"
+  "A constant in the range [-64, 63] for shift/rotate instructions."
+  (and (match_code "const_int")
+       (match_test "ival >= -0x40 && ival <= 0x3f")))
+
+(define_constraint "J"
+  "An unsigned 7-bit constant for conversion/nop/channel instructions."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 0x7f")))
+
+(define_constraint "K"
+  "A signed 10-bit constant for most arithmetic instructions."
+  (and (match_code "const_int")
+       (match_test "ival >= -0x200 && ival <= 0x1ff")))
+(define_constraint "M"
+  "A signed 16 bit immediate for @code{stop}."
+  (and (match_code "const_int")
+       (match_test "ival >= -0x8000ll && ival <= 0x7fffll")))
+
+(define_constraint "N"
+  "An unsigned 16-bit constant for @code{iohl} and @code{fsmbi}."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 0xffff")))
+
+(define_constraint "O"
+  "An unsigned 7-bit constant whose 3 least significant bits are 0."
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 0x7f && (ival & 7) == 0")))
+
+(define_constraint "P"
+  "An unsigned 3-bit constant for 16-byte rotates and shifts"
+  (and (match_code "const_int")
+       (match_test "ival >= 0 && ival <= 7")))
+
+\f
+;; Memory constraints
+
+(define_memory_constraint "R"
+  "Call operand, reg, for indirect calls"
+  (and (match_code "mem")
+       (match_test "GET_CODE(XEXP(op, 0)) == REG")))
+
+(define_memory_constraint "S"
+  "Call operand, symbol, for relative calls."
+  (and (match_code "mem")
+       (match_test "!TARGET_LARGE_MEM
+                   && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+                        || GET_CODE (XEXP (op, 0)) == LABEL_REF))")))
+
+(define_memory_constraint "T"
+  "Call operand, const_int, for absolute calls."
+  (and (match_code "mem")
+       (match_test "GET_CODE (XEXP (op, 0)) == CONST_INT
+                   && INTVAL (XEXP (op, 0)) >= 0
+                   && INTVAL (XEXP (op, 0)) <= 0x3ffff")))
+
+
diff --git a/gcc/config/spu/crt0.c b/gcc/config/spu/crt0.c
new file mode 100644 (file)
index 0000000..8c03abe
--- /dev/null
@@ -0,0 +1,130 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+  
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option)
+   any later version.
+  
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+  
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with
+   GCC to produce an executable, this does not cause the resulting executable
+   to be covered by the GNU General Public License.  The exception does not
+   however invalidate any other reasons why the executable file might be covered
+   by the GNU General Public License. */
+
+extern int main(int, unsigned long long, unsigned long long);
+void _start(int, unsigned long long, unsigned long long) __attribute__((__naked__));
+
+extern void exit(int);
+
+void _exit(int) __attribute__((__naked__));
+
+typedef void (*func_ptr) (void);
+typedef __attribute__ ((__vector_size__(16))) unsigned int vec_uint4;
+
+extern vec_uint4 __stack[];
+register vec_uint4 si_sp __asm__("$sp");
+register unsigned int si_r2 __asm__("$2");
+
+extern char _end[];
+
+/* If we want these aligned we need to do it in the linker script. */
+func_ptr __CTOR_LIST__[1]
+  __attribute__ ((__section__(".ctors"), __aligned__(4)))
+  = { (func_ptr) (-1) };
+
+static func_ptr __DTOR_LIST__[1]
+  __attribute__((__section__(".dtors"), __aligned__(4)))
+  = { (func_ptr) (-1) };
+
+
+/* According to the BE Linux ABI an SPU module is called with these
+ * parameters.  Also, $2 is set to the Available Stack Size.  */
+void
+_start(int spu_id,
+       unsigned long long param,
+       unsigned long long env)
+{
+  unsigned int stack_size;
+  unsigned int sp = (unsigned int)(__stack - 2);
+
+  /* Initialize the stack.  __stack has been set to point to the top
+     quadword of the stack.  The ABI requires at least a NULL terminated
+     back chain and lr save area.  For example:
+         +----------------+
+        | 0              |
+         +----------------+  <-  __stack (e.g., 0x3fff0)
+        | space for $lr  |
+         +----------------+
+        | back chain     |
+         +----------------+  <-  $sp  (e.g., __stack - 32, 0x3ffd0)
+  */
+  __stack[0] = (vec_uint4){0, 0, 0, 0};
+  __stack[-1] = (vec_uint4){0, 0, 0, 0};
+
+  /* Initialize the Available Stack Size word of the Stack Pointer
+   * information register.  The BE Linux ABI passes the stack size in
+   * $2, or use everything up to _end if $2 == 0. */
+  stack_size = si_r2 == 0 ? sp - (unsigned int)_end : si_r2;
+
+  __stack[-2] = (vec_uint4){(unsigned int)__stack, stack_size, 0, 0};
+
+  si_sp = (vec_uint4){sp, stack_size, 0, 0};
+
+
+  {
+    extern func_ptr __CTOR_END__[];
+    func_ptr *p;
+
+    /* The compiler assumes all symbols are 16 byte aligned, which is
+     * not the case for __CTOR_END__.  This inline assembly makes sure
+     * the address is loaded into a register for which the compiler does
+     * not assume anything about alignment. */
+    __asm__ ("\n" : "=r" (p) : "0" (__CTOR_END__ - 1));
+
+    for (; *p != (func_ptr) -1; p--)
+      (*p) ();
+  }
+
+  exit(main(spu_id, param, env));
+  __asm__ volatile ( " stop    0x20ff");
+}
+
+/* C99 requires _Exit */
+void _Exit(int) __attribute__((__weak__, __alias__("_exit")));
+
+void
+_exit(int rc)
+{
+  {
+    static func_ptr *p = 0;
+    if (!p)
+      {
+       /* See comment for __CTOR_END__ above. */
+       __asm__ ("" : "=r" (p) : "0" (__DTOR_LIST__ + 1));
+       for (; *p; p++)
+         (*p) ();
+      }
+  }
+  /* Some self modifying code to return 'rc' in the 'stop' insn. */
+  __asm__ volatile (
+    "  ori     $3, %0,0\n"
+    "  lqr     $4, 1f\n"
+    "  cbd     $5, 1f+3($sp)\n"
+    "  shufb   $0, %0, $4, $5\n"
+    "  stqr    $0, 1f\n"
+    "  sync\n"
+    "1:\n"
+    "  stop    0x2000\n"
+    : : "r" (rc) );
+}
+
diff --git a/gcc/config/spu/crtend.c b/gcc/config/spu/crtend.c
new file mode 100644 (file)
index 0000000..694a7ee
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with 
+   GCC to produce an executable, this does not cause the resulting executable 
+   to be covered by the GNU General Public License.  The exception does not 
+   however invalidate any other reasons why the executable file might be covered 
+   by the GNU General Public License. */
+
+typedef void (*func_ptr) (void);
+
+func_ptr __CTOR_END__[1]
+  __attribute__ ((section(".ctors"), aligned(sizeof(func_ptr))))
+  = { (func_ptr) (0) };
+
+func_ptr __DTOR_END__[1]
+  __attribute__((section(".dtors"), aligned(sizeof(func_ptr))))
+  = { (func_ptr) (0) };
diff --git a/gcc/config/spu/crti.asm b/gcc/config/spu/crti.asm
new file mode 100644 (file)
index 0000000..dd0aa3d
--- /dev/null
@@ -0,0 +1,53 @@
+#  Copyright (C) 2006 Free Software Foundation, Inc.
+#
+#  This file is free software; you can redistribute it and/or modify it under
+#  the terms of the GNU General Public License as published by the Free
+#  Software Foundation; either version 2 of the License, or (at your option) 
+#  any later version.
+#
+#  This file is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this file; see the file COPYING.  If not, write to the Free
+#  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+#  02110-1301, USA.  */
+# 
+#    As a special exception, if you link this library with files
+#    compiled with GCC to produce an executable, this does not cause
+#    the resulting executable to be covered by the GNU General Public License.
+#    This exception does not however invalidate any other reasons why
+#    the executable file might be covered by the GNU General Public License.
+# 
+
+# This file just make a stack frame for the contents of the .fini and
+# .init sections.  Users may put any desired instructions in those
+# sections.
+
+       # Note - this macro is complimented by the FUNC_END macro
+       # in crtn.asm.  If you change this macro you must also change
+       # that macro match.
+.macro FUNC_START
+       #  Create a stack frame and save any call-preserved registers
+       ai      $sp, $sp, -16
+       stqd    $lr, 0($sp)
+.endm
+               
+       .file           "crti.asm"
+
+       .section        ".init"
+       .align 2
+       .global _init
+_init:
+       FUNC_START
+       
+               
+       .section        ".fini"
+       .align  2
+       .global _fini
+_fini:
+       FUNC_START
+       
+# end of crti.asm
diff --git a/gcc/config/spu/crtn.asm b/gcc/config/spu/crtn.asm
new file mode 100644 (file)
index 0000000..27b5276
--- /dev/null
@@ -0,0 +1,54 @@
+#  Copyright (C) 2006 Free Software Foundation, Inc.
+#
+#  This file is free software; you can redistribute it and/or modify it under
+#  the terms of the GNU General Public License as published by the Free
+#  Software Foundation; either version 2 of the License, or (at your option) 
+#  any later version.
+#
+#  This file is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this file; see the file COPYING.  If not, write to the Free
+#  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+#  02110-1301, USA.  */
+# 
+#    As a special exception, if you link this library with files
+#    compiled with GCC to produce an executable, this does not cause
+#    the resulting executable to be covered by the GNU General Public License.
+#    This exception does not however invalidate any other reasons why
+#    the executable file might be covered by the GNU General Public License.
+# 
+
+# This file just makes sure that the .fini and .init sections do in
+# fact return.  Users may put any desired instructions in those sections.
+# This file is the last thing linked into any executable.
+
+       # Note - this macro is complimented by the FUNC_START macro
+       # in crti.asm.  If you change this macro you must also change
+       # that macro match.
+       #
+       # Note - we do not try any fancy optimisations of the return
+       # sequences here, it is just not worth it.  Instead keep things
+       # simple.  Restore all the save resgisters, including the link
+       # register and then perform the correct function return instruction.
+.macro FUNC_END
+       lqd     $lr, 0($sp)
+       ai      $sp, $sp, 16
+       bi      $lr
+.endm
+               
+       
+       .file           "crtn.asm"
+
+       .section        ".init"
+       ;;
+       FUNC_END
+       
+       .section        ".fini"
+       ;;
+       FUNC_END
+       
+# end of crtn.asm
diff --git a/gcc/config/spu/float_unsdidf.c b/gcc/config/spu/float_unsdidf.c
new file mode 100644 (file)
index 0000000..9b30949
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+  
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option)
+   any later version.
+  
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+  
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with
+   GCC to produce an executable, this does not cause the resulting executable
+   to be covered by the GNU General Public License.  The exception does not
+   however invalidate any other reasons why the executable file might be covered
+   by the GNU General Public License. */
+
+#include <spu_intrinsics.h>
+const unsigned char __didf_scale[16] __attribute__ ((__aligned__ (16))) = {
+  0x00, 0x00, 0x04, 0x3e,
+  0x00, 0x00, 0x04, 0x1e,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+const unsigned char __didf_pat[16] __attribute__ ((__aligned__ (16))) = {
+  0x02, 0x03, 0x10, 0x11,
+  0x12, 0x13, 0x80, 0x80,
+  0x06, 0x07, 0x14, 0x15,
+  0x16, 0x17, 0x80, 0x80
+};
+
+/* double __float_unsdidf (unsigned long long int) 
+   Construct two exact doubles representing the high and low parts (in
+   parallel), then add them. */
+qword __float_unsdidf (qword DI);
+qword
+__float_unsdidf (qword DI)
+{
+  qword t0, t1, t2, t3, t4, t5, t6, t7, t8;
+  t0 = si_clz (DI);
+  t1 = si_shl (DI, t0);
+  t2 = si_ceqi (t0, 32);
+  t3 = si_sf (t0, *(qword *) __didf_scale);
+  t4 = si_a (t1, t1);
+  t5 = si_andc (t3, t2);
+  t6 = si_shufb (t5, t4, *(qword *) __didf_pat);
+  t7 = si_shlqbii (t6, 4);
+  t8 = si_shlqbyi (t7, 8);
+  return si_dfa (t7, t8);
+}
diff --git a/gcc/config/spu/float_unssidf.c b/gcc/config/spu/float_unssidf.c
new file mode 100644 (file)
index 0000000..63d475b
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+  
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option)
+   any later version.
+  
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+  
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you link this library with files compiled with
+   GCC to produce an executable, this does not cause the resulting executable
+   to be covered by the GNU General Public License.  The exception does not
+   however invalidate any other reasons why the executable file might be covered
+   by the GNU General Public License. */
+
+#include <spu_intrinsics.h>
+const unsigned char __sidf_pat[16] __attribute__ ((__aligned__ (16))) = {
+  0x02, 0x03, 0x10, 0x11,
+  0x12, 0x13, 0x80, 0x80,
+  0x06, 0x07, 0x14, 0x15,
+  0x16, 0x17, 0x80, 0x80
+};
+
+/* double __float_unssidf (unsigned int SI) */
+qword __float_unssidf (qword SI);
+qword
+__float_unssidf (qword SI)
+{
+  qword t0, t1, t2, t3, t4, t5, t6, t7;
+  t0 = si_clz (SI);
+  t1 = si_il (1054);
+  t2 = si_shl (SI, t0);
+  t3 = si_ceqi (t0, 32);
+  t4 = si_sf (t0, t1);
+  t5 = si_a (t2, t2);
+  t6 = si_andc (t4, t3);
+  t7 = si_shufb (t6, t5, *(qword *)__sidf_pat);
+  return si_shlqbii (t7, 4);
+}
diff --git a/gcc/config/spu/predicates.md b/gcc/config/spu/predicates.md
new file mode 100644 (file)
index 0000000..0474d84
--- /dev/null
@@ -0,0 +1,100 @@
+;; Predicate definitions for CELL SPU
+;; Copyright (C) 2006 Free Software Foundation, Inc.
+;;
+;; This file is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 2 of the License, or (at your option) 
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file; see the file COPYING.  If not, write to the Free
+;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+(define_predicate "spu_reg_operand"
+  (and (match_operand 0 "register_operand")
+       (ior (not (match_code "subreg"))
+            (match_test "valid_subreg (op)"))))
+
+(define_predicate "spu_nonimm_operand"
+  (and (match_operand 0 "nonimmediate_operand")
+       (ior (not (match_code "subreg"))
+            (match_test "valid_subreg (op)"))))
+
+(define_predicate "spu_nonmem_operand"
+  (and (match_operand 0 "nonmemory_operand")
+       (ior (not (match_code "subreg"))
+            (match_test "valid_subreg (op)"))))
+
+(define_predicate "spu_mem_operand"
+  (and (match_operand 0 "memory_operand")
+       (match_test "reload_in_progress || reload_completed || aligned_mem_p (op)")))
+
+(define_predicate "call_operand"
+  (and (match_code "mem")
+       (match_test "(!TARGET_LARGE_MEM && satisfies_constraint_S (op))
+                   || (satisfies_constraint_R (op)
+                       && REGNO (XEXP (op, 0)) != FRAME_POINTER_REGNUM
+                       && REGNO (XEXP (op, 0)) != ARG_POINTER_REGNUM
+                       && (REGNO (XEXP (op, 0)) < FIRST_PSEUDO_REGISTER
+                           || REGNO (XEXP (op, 0)) > LAST_VIRTUAL_REGISTER))")))
+
+(define_predicate "vec_imm_operand"
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "spu_legitimate_constant_p (op)")))
+
+(define_predicate "spu_arith_operand"
+  (match_code "reg,subreg,const_int,const_vector")
+  {
+    if (spu_reg_operand (op, mode))
+      return 1;
+    if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_VECTOR)
+      return arith_immediate_p (op, mode, -0x200, 0x1ff);
+    return 0;
+  })
+
+(define_predicate "spu_logical_operand"
+  (match_code "reg,subreg,const_int,const_double,const_vector")
+  {
+    if (spu_reg_operand (op, mode))
+      return 1;
+    if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
+       || GET_CODE (op) == CONST_VECTOR)
+      return logical_immediate_p (op, mode);
+    return 0;
+  })
+
+(define_predicate "spu_ior_operand"
+  (match_code "reg,subreg,const_int,const_double,const_vector")
+  {
+    if (spu_reg_operand (op, mode))
+      return 1;
+    if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
+       || GET_CODE (op) == CONST_VECTOR)
+      return logical_immediate_p (op, mode)
+            || iohl_immediate_p (op, mode);
+    return 0;
+  })
+
+(define_predicate "spu_shift_operand"
+  (match_code "reg,subreg,const_int,const_vector")
+  {
+    if (spu_reg_operand (op, mode))
+      return 1;
+    if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_VECTOR)
+      return arith_immediate_p (op, mode, -0x40, 0x3f);
+    return 0;
+  })
+
+;; Return 1 if OP is a comparison operation that is valid for a branch insn.
+;; We only check the opcode against the mode of the register value here. 
+(define_predicate "branch_comparison_operator"
+  (and (match_code "eq,ne")
+       (ior (match_test "GET_MODE (XEXP (op, 0)) == HImode")
+           (match_test "GET_MODE (XEXP (op, 0)) == SImode"))))
+
diff --git a/gcc/config/spu/spu-builtins.def b/gcc/config/spu/spu-builtins.def
new file mode 100644 (file)
index 0000000..af8a888
--- /dev/null
@@ -0,0 +1,715 @@
+/* Definitions of builtin fuctions for the Synergistic Processing Unit (SPU). */
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+
+/* The first argument to these macros is the return type of the builtin,
+ * the rest are arguments of the builtin. */
+#define _A1(a)       {a, SPU_BTI_END_OF_PARAMS}
+#define _A2(a,b)     {a, b, SPU_BTI_END_OF_PARAMS}
+#define _A3(a,b,c)   {a, b, c, SPU_BTI_END_OF_PARAMS}
+#define _A4(a,b,c,d) {a, b, c, d, SPU_BTI_END_OF_PARAMS}
+
+/* definitions to support si intrinisic functions: (These and other builtin 
+ * definitions must preceed definitions of the overloaded generic intrinsics */
+
+DEF_BUILTIN (SI_LQD,         CODE_FOR_spu_lqd,       "si_lqd",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10_4))
+DEF_BUILTIN (SI_LQX,         CODE_FOR_spu_lqx,       "si_lqx",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_LQA,         CODE_FOR_spu_lqa,       "si_lqa",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_U16_2))
+DEF_BUILTIN (SI_LQR,         CODE_FOR_spu_lqr,       "si_lqr",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_S16_2))
+DEF_BUILTIN (SI_STQD,        CODE_FOR_spu_stqd,      "si_stqd",        B_INSN,   _A4(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10_4))
+DEF_BUILTIN (SI_STQX,        CODE_FOR_spu_stqx,      "si_stqx",        B_INSN,   _A4(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_STQA,        CODE_FOR_spu_stqa,      "si_stqa",        B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_U16_2))
+DEF_BUILTIN (SI_STQR,        CODE_FOR_spu_stqr,      "si_stqr",        B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_S16_2))
+DEF_BUILTIN (SI_CBD,         CODE_FOR_spu_cbx,       "si_cbd",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7))
+DEF_BUILTIN (SI_CBX,         CODE_FOR_spu_cbx,       "si_cbx",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CHD,         CODE_FOR_spu_chx,       "si_chd",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7))
+DEF_BUILTIN (SI_CHX,         CODE_FOR_spu_chx,       "si_chx",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CWD,         CODE_FOR_spu_cwx,       "si_cwd",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7))
+DEF_BUILTIN (SI_CWX,         CODE_FOR_spu_cwx,       "si_cwx",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CDD,         CODE_FOR_spu_cdx,       "si_cdd",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S7))
+DEF_BUILTIN (SI_CDX,         CODE_FOR_spu_cdx,       "si_cdx",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ILH,         CODE_FOR_movv8hi,       "si_ilh",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_16))
+DEF_BUILTIN (SI_ILHU,        CODE_FOR_spu_ilhu,      "si_ilhu",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_16))
+DEF_BUILTIN (SI_IL,          CODE_FOR_movv4si,       "si_il",          B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_S16))
+DEF_BUILTIN (SI_ILA,         CODE_FOR_movv4si,       "si_ila",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_U18))
+DEF_BUILTIN (SI_IOHL,        CODE_FOR_iorv4si3,      "si_iohl",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U16))
+DEF_BUILTIN (SI_FSMBI,       CODE_FOR_spu_fsmb,      "si_fsmbi",       B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_16))
+DEF_BUILTIN (SI_AH,          CODE_FOR_addv8hi3,      "si_ah",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_AHI,         CODE_FOR_addv8hi3,      "si_ahi",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_A,           CODE_FOR_addv4si3,      "si_a",           B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_AI,          CODE_FOR_addv4si3,      "si_ai",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_ADDX,        CODE_FOR_addx_v4si,     "si_addx",        B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CG,          CODE_FOR_cg_v4si,       "si_cg",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CGX,         CODE_FOR_cgx_v4si,      "si_cgx",         B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SFH,         CODE_FOR_spu_sfh,       "si_sfh",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SFHI,        CODE_FOR_spu_sfh,       "si_sfhi",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_SF,          CODE_FOR_spu_sf,        "si_sf",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SFI,         CODE_FOR_spu_sf,        "si_sfi",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_SFX,         CODE_FOR_spu_sfx,       "si_sfx",         B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_BG,          CODE_FOR_spu_bg,        "si_bg",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_BGX,         CODE_FOR_spu_bgx,       "si_bgx",         B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPY,         CODE_FOR_spu_mpy,       "si_mpy",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYU,        CODE_FOR_spu_mpyu,      "si_mpyu",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYI,        CODE_FOR_spu_mpy,       "si_mpyi",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_MPYUI,       CODE_FOR_spu_mpyu,      "si_mpyui",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_MPYA,        CODE_FOR_spu_mpya,      "si_mpya",        B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYH,        CODE_FOR_spu_mpyh,      "si_mpyh",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYS,        CODE_FOR_spu_mpys,      "si_mpys",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYHH,       CODE_FOR_spu_mpyhh,     "si_mpyhh",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYHHU,      CODE_FOR_spu_mpyhhu,    "si_mpyhhu",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYHHA,      CODE_FOR_spu_mpyhha,    "si_mpyhha",      B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_MPYHHAU,     CODE_FOR_spu_mpyhhau,   "si_mpyhhau",     B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CLZ,         CODE_FOR_clzv4si2,      "si_clz",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CNTB,        CODE_FOR_cntb_v16qi,    "si_cntb",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FSMB,        CODE_FOR_spu_fsmb,      "si_fsmb",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FSMH,        CODE_FOR_spu_fsmh,      "si_fsmh",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FSM,         CODE_FOR_spu_fsm,       "si_fsm",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_GBB,         CODE_FOR_spu_gbb,       "si_gbb",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_GBH,         CODE_FOR_spu_gbh,       "si_gbh",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_GB,          CODE_FOR_spu_gb,        "si_gb",          B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_AVGB,        CODE_FOR_spu_avgb,      "si_avgb",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ABSDB,       CODE_FOR_spu_absdb,     "si_absdb",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SUMB,        CODE_FOR_spu_sumb,      "si_sumb",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_XSBH,        CODE_FOR_spu_xsbh,      "si_xsbh",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_XSHW,        CODE_FOR_spu_xshw,      "si_xshw",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_XSWD,        CODE_FOR_spu_xswd,      "si_xswd",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_AND,         CODE_FOR_andv16qi3,     "si_and",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ANDC,        CODE_FOR_andc_v16qi,    "si_andc",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ANDBI,       CODE_FOR_andv16qi3,     "si_andbi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_ANDHI,       CODE_FOR_andv8hi3,      "si_andhi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_ANDI,        CODE_FOR_andv4si3,      "si_andi",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_OR,          CODE_FOR_iorv16qi3,     "si_or",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ORC,         CODE_FOR_orc_v16qi,     "si_orc",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ORBI,        CODE_FOR_iorv16qi3,     "si_orbi",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_ORHI,        CODE_FOR_iorv8hi3,      "si_orhi",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_ORI,         CODE_FOR_iorv4si3,      "si_ori",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_ORX,         CODE_FOR_spu_orx,       "si_orx",         B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_XOR,         CODE_FOR_xorv16qi3,     "si_xor",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_XORBI,       CODE_FOR_xorv16qi3,     "si_xorbi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_XORHI,       CODE_FOR_xorv8hi3,      "si_xorhi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_XORI,        CODE_FOR_xorv4si3,      "si_xori",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_NAND,        CODE_FOR_nand_v16qi,    "si_nand",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_NOR,         CODE_FOR_nor_v16qi,     "si_nor",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_EQV,         CODE_FOR_eqv_v16qi,     "si_eqv",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SELB,        CODE_FOR_selb,          "si_selb",        B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SHUFB,       CODE_FOR_shufb,         "si_shufb",       B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SHLH,        CODE_FOR_ashlv8hi3,     "si_shlh",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SHLHI,       CODE_FOR_ashlv8hi3,     "si_shlhi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_SHL,         CODE_FOR_ashlv4si3,     "si_shl",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SHLI,        CODE_FOR_ashlv4si3,     "si_shli",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_SHLQBI,      CODE_FOR_shlqbi_ti,     "si_shlqbi",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SHLQBII,     CODE_FOR_shlqbi_ti,     "si_shlqbii",     B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_SHLQBY,      CODE_FOR_shlqby_ti,     "si_shlqby",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_SHLQBYI,     CODE_FOR_shlqby_ti,     "si_shlqbyi",     B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_SHLQBYBI,    CODE_FOR_shlqbybi_ti,   "si_shlqbybi",    B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTH,        CODE_FOR_rotlv8hi3,     "si_roth",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTHI,       CODE_FOR_rotlv8hi3,     "si_rothi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROT,         CODE_FOR_rotlv4si3,     "si_rot",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTI,        CODE_FOR_rotlv4si3,     "si_roti",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTQBY,      CODE_FOR_rotqby_ti,     "si_rotqby",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTQBYI,     CODE_FOR_rotqby_ti,     "si_rotqbyi",     B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTQBYBI,    CODE_FOR_rotqbybi_ti,   "si_rotqbybi",    B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTQBI,      CODE_FOR_rotqbi_ti,     "si_rotqbi",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTQBII,     CODE_FOR_rotqbi_ti,     "si_rotqbii",     B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTHM,       CODE_FOR_rotm_v8hi,     "si_rothm",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTHMI,      CODE_FOR_rotm_v8hi,     "si_rothmi",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTM,        CODE_FOR_rotm_v4si,     "si_rotm",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTMI,       CODE_FOR_rotm_v4si,     "si_rotmi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTQMBY,     CODE_FOR_rotqmby_ti,    "si_rotqmby",     B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTQMBYI,    CODE_FOR_rotqmby_ti,    "si_rotqmbyi",    B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTQMBI,     CODE_FOR_rotqmbi_ti,    "si_rotqmbi",     B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTQMBII,    CODE_FOR_rotqmbi_ti,    "si_rotqmbii",    B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTQMBYBI,   CODE_FOR_rotqmbybi_ti,  "si_rotqmbybi",   B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTMAH,      CODE_FOR_rotma_v8hi,    "si_rotmah",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTMAHI,     CODE_FOR_rotma_v8hi,    "si_rotmahi",     B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_ROTMA,       CODE_FOR_rotma_v4si,    "si_rotma",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_ROTMAI,      CODE_FOR_rotma_v4si,    "si_rotmai",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_7))
+DEF_BUILTIN (SI_HEQ,         CODE_FOR_spu_heq,       "si_heq",         B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_HEQI,        CODE_FOR_spu_heq,       "si_heqi",        B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_HGT,         CODE_FOR_spu_hgt,       "si_hgt",         B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_HGTI,        CODE_FOR_spu_hgt,       "si_hgti",        B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_HLGT,        CODE_FOR_spu_hlgt,      "si_hlgt",        B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_HLGTI,       CODE_FOR_spu_hlgt,      "si_hlgti",       B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CEQB,        CODE_FOR_ceq_v16qi,     "si_ceqb",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CEQBI,       CODE_FOR_ceq_v16qi,     "si_ceqbi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CEQH,        CODE_FOR_ceq_v8hi,      "si_ceqh",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CEQHI,       CODE_FOR_ceq_v8hi,      "si_ceqhi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CEQ,         CODE_FOR_ceq_v4si,      "si_ceq",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CEQI,        CODE_FOR_ceq_v4si,      "si_ceqi",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CGTB,        CODE_FOR_cgt_v16qi,     "si_cgtb",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CGTBI,       CODE_FOR_cgt_v16qi,     "si_cgtbi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CGTH,        CODE_FOR_cgt_v8hi,      "si_cgth",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CGTHI,       CODE_FOR_cgt_v8hi,      "si_cgthi",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CGT,         CODE_FOR_cgt_v4si,      "si_cgt",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CGTI,        CODE_FOR_cgt_v4si,      "si_cgti",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CLGTB,       CODE_FOR_clgt_v16qi,    "si_clgtb",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CLGTBI,      CODE_FOR_clgt_v16qi,    "si_clgtbi",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CLGTH,       CODE_FOR_clgt_v8hi,     "si_clgth",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CLGTHI,      CODE_FOR_clgt_v8hi,     "si_clgthi",      B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_CLGT,        CODE_FOR_clgt_v4si,     "si_clgt",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CLGTI,       CODE_FOR_clgt_v4si,     "si_clgti",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10))
+DEF_BUILTIN (SI_FA,          CODE_FOR_addv4sf3,      "si_fa",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_DFA,         CODE_FOR_addv2df3,      "si_dfa",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FS,          CODE_FOR_subv4sf3,      "si_fs",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_DFS,         CODE_FOR_subv2df3,      "si_dfs",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FM,          CODE_FOR_mulv4sf3,      "si_fm",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_DFM,         CODE_FOR_mulv2df3,      "si_dfm",         B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FMA,         CODE_FOR_fma_v4sf,      "si_fma",         B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_DFMA,        CODE_FOR_fma_v2df,      "si_dfma",        B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_DFNMA,       CODE_FOR_fnma_v2df,     "si_dfnma",       B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FNMS,        CODE_FOR_fnms_v4sf,     "si_fnms",        B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_DFNMS,       CODE_FOR_fnms_v2df,     "si_dfnms",       B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FMS,         CODE_FOR_fms_v4sf,      "si_fms",         B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_DFMS,        CODE_FOR_fms_v2df,      "si_dfms",        B_INSN,   _A4(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FREST,       CODE_FOR_frest_v4sf,    "si_frest",       B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FRSQEST,     CODE_FOR_frsqest_v4sf,  "si_frsqest",     B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FI,          CODE_FOR_fi_v4sf,       "si_fi",          B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_CSFLT,       CODE_FOR_spu_csflt,     "si_csflt",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7))
+DEF_BUILTIN (SI_CFLTS,       CODE_FOR_spu_cflts,     "si_cflts",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7))
+DEF_BUILTIN (SI_CUFLT,       CODE_FOR_spu_cuflt,     "si_cuflt",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7))
+DEF_BUILTIN (SI_CFLTU,       CODE_FOR_spu_cfltu,     "si_cfltu",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_U7))
+DEF_BUILTIN (SI_FRDS,        CODE_FOR_spu_frds,      "si_frds",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FESD,        CODE_FOR_spu_fesd,      "si_fesd",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FCEQ,        CODE_FOR_ceq_v4sf,      "si_fceq",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FCMEQ,       CODE_FOR_cmeq_v4sf,     "si_fcmeq",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FCGT,        CODE_FOR_cgt_v4sf,      "si_fcgt",        B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FCMGT,       CODE_FOR_cmgt_v4sf,     "si_fcmgt",       B_INSN,   _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_STOP,        CODE_FOR_spu_stop,      "si_stop",        B_INSN,   _A2(SPU_BTI_VOID,     SPU_BTI_U14))
+DEF_BUILTIN (SI_STOPD,       CODE_FOR_spu_stopd,     "si_stopd",       B_INSN,   _A4(SPU_BTI_VOID,     SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_LNOP,        CODE_FOR_lnop,          "si_lnop",        B_INSN,   _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SI_NOP,         CODE_FOR_nop,           "si_nop",         B_INSN,   _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SI_SYNC,        CODE_FOR_sync,          "si_sync",        B_INSN,   _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SI_SYNCC,       CODE_FOR_syncc,         "si_syncc",       B_INSN,   _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SI_DSYNC,       CODE_FOR_dsync,         "si_dsync",       B_INSN,   _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SI_MFSPR,       CODE_FOR_spu_mfspr,     "si_mfspr",       B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_U7))
+DEF_BUILTIN (SI_MTSPR,       CODE_FOR_spu_mtspr,     "si_mtspr",       B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_U7,       SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FSCRRD,      CODE_FOR_spu_fscrrd,    "si_fscrrd",      B_INSN,   _A1(SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FSCRWR,      CODE_FOR_spu_fscrwr,    "si_fscrwr",      B_INSN,   _A2(SPU_BTI_VOID,     SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_RDCH,        CODE_FOR_spu_rdch,      "si_rdch",        B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_U7))
+DEF_BUILTIN (SI_RCHCNT,      CODE_FOR_spu_rchcnt,    "si_rchcnt",      B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_U7))
+DEF_BUILTIN (SI_WRCH,        CODE_FOR_spu_wrch,      "si_wrch",        B_INSN,   _A3(SPU_BTI_VOID,     SPU_BTI_U7,       SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_CHAR,     CODE_FOR_spu_convert,   "si_to_char",     B_INSN,   _A2(SPU_BTI_INTQI,    SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_UCHAR,    CODE_FOR_spu_convert,   "si_to_uchar",    B_INSN,   _A2(SPU_BTI_UINTQI,   SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_SHORT,    CODE_FOR_spu_convert,   "si_to_short",    B_INSN,   _A2(SPU_BTI_INTHI,    SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_USHORT,   CODE_FOR_spu_convert,   "si_to_ushort",   B_INSN,   _A2(SPU_BTI_UINTHI,   SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_INT,      CODE_FOR_spu_convert,   "si_to_int",      B_INSN,   _A2(SPU_BTI_INTSI,    SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_UINT,     CODE_FOR_spu_convert,   "si_to_uint",     B_INSN,   _A2(SPU_BTI_UINTSI,   SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_LONG,     CODE_FOR_spu_convert,   "si_to_long",     B_INSN,   _A2(SPU_BTI_INTDI,    SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_ULONG,    CODE_FOR_spu_convert,   "si_to_ulong",    B_INSN,   _A2(SPU_BTI_UINTDI,   SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_FLOAT,    CODE_FOR_spu_convert,   "si_to_float",    B_INSN,   _A2(SPU_BTI_FLOAT,    SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_DOUBLE,   CODE_FOR_spu_convert,   "si_to_double",   B_INSN,   _A2(SPU_BTI_DOUBLE,   SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_TO_PTR,      CODE_FOR_spu_convert,   "si_to_ptr",      B_INSN,   _A2(SPU_BTI_PTR,      SPU_BTI_QUADWORD))
+DEF_BUILTIN (SI_FROM_CHAR,   CODE_FOR_spu_convert,   "si_from_char",   B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_INTQI))
+DEF_BUILTIN (SI_FROM_UCHAR,  CODE_FOR_spu_convert,   "si_from_uchar",  B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTQI))
+DEF_BUILTIN (SI_FROM_SHORT,  CODE_FOR_spu_convert,   "si_from_short",  B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_INTHI))
+DEF_BUILTIN (SI_FROM_USHORT, CODE_FOR_spu_convert,   "si_from_ushort", B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTHI))
+DEF_BUILTIN (SI_FROM_INT,    CODE_FOR_spu_convert,   "si_from_int",    B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_INTSI))
+DEF_BUILTIN (SI_FROM_UINT,   CODE_FOR_spu_convert,   "si_from_uint",   B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTSI))
+DEF_BUILTIN (SI_FROM_LONG,   CODE_FOR_spu_convert,   "si_from_long",   B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_INTDI))
+DEF_BUILTIN (SI_FROM_ULONG,  CODE_FOR_spu_convert,   "si_from_ulong",  B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_UINTDI))
+DEF_BUILTIN (SI_FROM_FLOAT,  CODE_FOR_spu_convert,   "si_from_float",  B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_FLOAT))
+DEF_BUILTIN (SI_FROM_DOUBLE, CODE_FOR_spu_convert,   "si_from_double", B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_DOUBLE))
+DEF_BUILTIN (SI_FROM_PTR,    CODE_FOR_spu_convert,   "si_from_ptr",    B_INSN,   _A2(SPU_BTI_QUADWORD, SPU_BTI_PTR))
+
+/* definitions to support generic builtin functions: */
+
+DEF_BUILTIN (SPU_CONVTS,     CODE_FOR_spu_cflts,      "spu_convts",     B_INSN,     _A3(SPU_BTI_V4SI,     SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_CONVTU,     CODE_FOR_spu_cfltu,      "spu_convtu",     B_INSN,     _A3(SPU_BTI_UV4SI,    SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_ROUNDTF,    CODE_FOR_spu_frds,       "spu_roundtf",    B_INSN,     _A2(SPU_BTI_V4SF,     SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_MULH,       CODE_FOR_spu_mpyh,       "spu_mulh",       B_INSN,     _A3(SPU_BTI_V4SI,     SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_MULSR,      CODE_FOR_spu_mpys,       "spu_mulsr",      B_INSN,     _A3(SPU_BTI_V4SI,     SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_FREST,      CODE_FOR_frest_v4sf,     "spu_frest",      B_INSN,     _A2(SPU_BTI_V4SF,     SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_FRSQEST,    CODE_FOR_frsqest_v4sf,   "spu_frsqest",    B_INSN,     _A2(SPU_BTI_V4SF,     SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_NMADD,      CODE_FOR_fnma_v2df,      "spu_nmadd",      B_INSN,     _A4(SPU_BTI_V2DF,     SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_ABSD,       CODE_FOR_spu_absdb,      "spu_absd",       B_INSN,     _A3(SPU_BTI_UV16QI,   SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_AVG,        CODE_FOR_spu_avgb,       "spu_avg",        B_INSN,     _A3(SPU_BTI_UV16QI,   SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SUMB,       CODE_FOR_spu_sumb,       "spu_sumb",       B_INSN,     _A3(SPU_BTI_UV8HI,    SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_BISLED,     CODE_FOR_spu_bisled,     "spu_bisled",     B_BISLED,   _A3(SPU_BTI_VOID,    SPU_BTI_PTR,   SPU_BTI_PTR))
+DEF_BUILTIN (SPU_BISLED_D,   CODE_FOR_spu_bisledd,    "spu_bisled_d",   B_BISLED,   _A3(SPU_BTI_VOID,    SPU_BTI_PTR,   SPU_BTI_PTR))
+DEF_BUILTIN (SPU_BISLED_E,   CODE_FOR_spu_bislede,    "spu_bisled_e",   B_BISLED,   _A3(SPU_BTI_VOID,    SPU_BTI_PTR,   SPU_BTI_PTR))
+DEF_BUILTIN (SPU_CMPABSEQ,   CODE_FOR_cmeq_v4sf,      "spu_cmpabseq",   B_INSN,     _A3(SPU_BTI_UV4SI,    SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_CMPABSGT,   CODE_FOR_cmgt_v4sf,      "spu_cmpabsgt",   B_INSN,     _A3(SPU_BTI_UV4SI,    SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_IDISABLE,   CODE_FOR_spu_idisable,   "spu_idisable",   B_INSN,     _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_IENABLE,    CODE_FOR_spu_ienable,    "spu_ienable",    B_INSN,     _A1(SPU_BTI_VOID))
+
+/* definitions to support overloaded generic builtin functions:  */
+
+DEF_BUILTIN (SPU_CONVTF,           CODE_FOR_nothing,       "spu_convtf",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_CONVTF_0,         CODE_FOR_spu_cuflt,     "spu_convtf_0",         B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_CONVTF_1,         CODE_FOR_spu_csflt,     "spu_convtf_1",         B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_EXTEND,           CODE_FOR_nothing,       "spu_extend",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_EXTEND_0,         CODE_FOR_spu_xsbh,      "spu_extend_0",         B_INTERNAL, _A2(SPU_BTI_V8HI,   SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_EXTEND_1,         CODE_FOR_spu_xshw,      "spu_extend_1",         B_INTERNAL, _A2(SPU_BTI_V4SI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_EXTEND_2,         CODE_FOR_spu_xswd,      "spu_extend_2",         B_INTERNAL, _A2(SPU_BTI_V2DI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_EXTEND_3,         CODE_FOR_spu_fesd,      "spu_extend_3",         B_INTERNAL, _A2(SPU_BTI_V2DF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_ADD,              CODE_FOR_nothing,       "spu_add",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_ADD_0,            CODE_FOR_addv4si3,      "spu_add_0",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_ADD_1,            CODE_FOR_addv4si3,      "spu_add_1",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_ADD_2,            CODE_FOR_addv8hi3,      "spu_add_2",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_ADD_3,            CODE_FOR_addv8hi3,      "spu_add_3",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_ADD_4,            CODE_FOR_addv4sf3,      "spu_add_4",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_ADD_5,            CODE_FOR_addv2df3,      "spu_add_5",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_ADD_6,            CODE_FOR_addv8hi3,      "spu_add_6",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_ADD_7,            CODE_FOR_addv8hi3,      "spu_add_7",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_ADD_8,            CODE_FOR_addv4si3,      "spu_add_8",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_ADD_9,            CODE_FOR_addv4si3,      "spu_add_9",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_ADDX,             CODE_FOR_nothing,       "spu_addx",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_ADDX_0,           CODE_FOR_addx_v4si,     "spu_addx_0",           B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_ADDX_1,           CODE_FOR_addx_v4si,     "spu_addx_1",           B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_GENC,             CODE_FOR_nothing,       "spu_genc",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_GENC_0,           CODE_FOR_cg_v4si,       "spu_genc_0",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_GENC_1,           CODE_FOR_cg_v4si,       "spu_genc_1",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_GENCX,            CODE_FOR_nothing,       "spu_gencx",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_GENCX_0,          CODE_FOR_cgx_v4si,      "spu_gencx_0",          B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_GENCX_1,          CODE_FOR_cgx_v4si,      "spu_gencx_1",          B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_MADD,             CODE_FOR_nothing,       "spu_madd",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MADD_0,           CODE_FOR_spu_mpya,      "spu_madd_0",           B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_MADD_1,           CODE_FOR_fma_v4sf,      "spu_madd_1",           B_INTERNAL, _A4(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_MADD_2,           CODE_FOR_fma_v2df,      "spu_madd_2",           B_INTERNAL, _A4(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_MSUB,             CODE_FOR_nothing,       "spu_msub",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MSUB_0,           CODE_FOR_fms_v4sf,      "spu_msub_0",           B_INTERNAL, _A4(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_MSUB_1,           CODE_FOR_fms_v2df,      "spu_msub_1",           B_INTERNAL, _A4(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_MHHADD,           CODE_FOR_nothing,       "spu_mhhadd",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MHHADD_0,         CODE_FOR_spu_mpyhhau,   "spu_mhhadd_0",         B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_MHHADD_1,         CODE_FOR_spu_mpyhha,    "spu_mhhadd_1",         B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_MULE,             CODE_FOR_nothing,       "spu_mule",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MULE_0,           CODE_FOR_spu_mpyhhu,    "spu_mule_0",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_MULE_1,           CODE_FOR_spu_mpyhh,     "spu_mule_1",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_MUL,              CODE_FOR_nothing,       "spu_mul",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MUL_0,            CODE_FOR_mulv4sf3,      "spu_mul_0",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_MUL_1,            CODE_FOR_mulv2df3,      "spu_mul_1",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_MULO,             CODE_FOR_nothing,       "spu_mulo",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MULO_0,           CODE_FOR_spu_mpy,       "spu_mulo_0",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_MULO_1,           CODE_FOR_spu_mpyu,      "spu_mulo_1",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_MULO_2,           CODE_FOR_spu_mpy,       "spu_mulo_2",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_MULO_3,           CODE_FOR_spu_mpyu,      "spu_mulo_3",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_NMSUB,            CODE_FOR_nothing,       "spu_nmsub",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_NMSUB_0,          CODE_FOR_fnms_v4sf,     "spu_nmsub_0",          B_INTERNAL, _A4(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_NMSUB_1,          CODE_FOR_fnms_v2df,     "spu_nmsub_1",          B_INTERNAL, _A4(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_SUB,              CODE_FOR_nothing,       "spu_sub",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SUB_0,            CODE_FOR_subv8hi3,      "spu_sub_0",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_SUB_1,            CODE_FOR_subv8hi3,      "spu_sub_1",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_SUB_2,            CODE_FOR_subv4si3,      "spu_sub_2",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SUB_3,            CODE_FOR_subv4si3,      "spu_sub_3",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_SUB_4,            CODE_FOR_subv4sf3,      "spu_sub_4",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_SUB_5,            CODE_FOR_subv2df3,      "spu_sub_5",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_SUB_6,            CODE_FOR_subv8hi3,      "spu_sub_6",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UINTHI, SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_SUB_7,            CODE_FOR_subv8hi3,      "spu_sub_7",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_INTHI,  SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_SUB_8,            CODE_FOR_subv4si3,      "spu_sub_8",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UINTSI, SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SUB_9,            CODE_FOR_subv4si3,      "spu_sub_9",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_INTSI,  SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_SUBX,             CODE_FOR_nothing,       "spu_subx",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SUBX_0,           CODE_FOR_sfx_v4si,      "spu_subx_0",           B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SUBX_1,           CODE_FOR_sfx_v4si,      "spu_subx_1",           B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_GENB,             CODE_FOR_nothing,       "spu_genb",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_GENB_0,           CODE_FOR_bg_v4si,       "spu_genb_0",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_GENB_1,           CODE_FOR_bg_v4si,       "spu_genb_1",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_GENBX,            CODE_FOR_nothing,       "spu_genbx",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_GENBX_0,          CODE_FOR_bgx_v4si,      "spu_genbx_0",          B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_GENBX_1,          CODE_FOR_bgx_v4si,      "spu_genbx_1",          B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_CMPEQ,            CODE_FOR_nothing,       "spu_cmpeq",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_CMPEQ_0,          CODE_FOR_ceq_v16qi,     "spu_cmpeq_0",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_CMPEQ_1,          CODE_FOR_ceq_v16qi,     "spu_cmpeq_1",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_CMPEQ_2,          CODE_FOR_ceq_v8hi,      "spu_cmpeq_2",          B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_CMPEQ_3,          CODE_FOR_ceq_v8hi,      "spu_cmpeq_3",          B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_CMPEQ_4,          CODE_FOR_ceq_v4si,      "spu_cmpeq_4",          B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_CMPEQ_5,          CODE_FOR_ceq_v4si,      "spu_cmpeq_5",          B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_CMPEQ_6,          CODE_FOR_ceq_v4sf,      "spu_cmpeq_6",          B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_CMPEQ_7,          CODE_FOR_ceq_v16qi,     "spu_cmpeq_7",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_CMPEQ_8,          CODE_FOR_ceq_v16qi,     "spu_cmpeq_8",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_CMPEQ_9,          CODE_FOR_ceq_v8hi,      "spu_cmpeq_9",          B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_CMPEQ_10,         CODE_FOR_ceq_v8hi,      "spu_cmpeq_10",         B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_CMPEQ_11,         CODE_FOR_ceq_v4si,      "spu_cmpeq_11",         B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_CMPEQ_12,         CODE_FOR_ceq_v4si,      "spu_cmpeq_12",         B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_CMPGT,            CODE_FOR_nothing,       "spu_cmpgt",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_CMPGT_0,          CODE_FOR_clgt_v16qi,    "spu_cmpgt_0",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_CMPGT_1,          CODE_FOR_cgt_v16qi,     "spu_cmpgt_1",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_CMPGT_2,          CODE_FOR_clgt_v8hi,     "spu_cmpgt_2",          B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_CMPGT_3,          CODE_FOR_cgt_v8hi,      "spu_cmpgt_3",          B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_CMPGT_4,          CODE_FOR_clgt_v4si,     "spu_cmpgt_4",          B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_CMPGT_5,          CODE_FOR_cgt_v4si,      "spu_cmpgt_5",          B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_CMPGT_6,          CODE_FOR_cgt_v4sf,      "spu_cmpgt_6",          B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_CMPGT_7,          CODE_FOR_clgt_v16qi,    "spu_cmpgt_7",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_CMPGT_8,          CODE_FOR_cgt_v16qi,     "spu_cmpgt_8",          B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_V16QI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_CMPGT_9,          CODE_FOR_clgt_v8hi,     "spu_cmpgt_9",          B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_CMPGT_10,         CODE_FOR_cgt_v8hi,      "spu_cmpgt_10",         B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_CMPGT_11,         CODE_FOR_cgt_v4si,      "spu_cmpgt_11",         B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_CMPGT_12,         CODE_FOR_clgt_v4si,     "spu_cmpgt_12",         B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_HCMPEQ,           CODE_FOR_nothing,       "spu_hcmpeq",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_HCMPEQ_0,         CODE_FOR_spu_heq,       "spu_hcmpeq_0",         B_INTERNAL, _A3(SPU_BTI_VOID,  SPU_BTI_INTSI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_HCMPEQ_1,         CODE_FOR_spu_heq,       "spu_hcmpeq_1",         B_INTERNAL, _A3(SPU_BTI_VOID,  SPU_BTI_UINTSI, SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_HCMPGT,           CODE_FOR_nothing,       "spu_hcmpgt",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_HCMPGT_0,         CODE_FOR_spu_hgt,       "spu_hcmpgt_0",         B_INTERNAL, _A3(SPU_BTI_VOID,  SPU_BTI_INTSI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_HCMPGT_1,         CODE_FOR_spu_hlgt,      "spu_hcmpgt_1",         B_INTERNAL, _A3(SPU_BTI_VOID,  SPU_BTI_UINTSI, SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_CNTB,             CODE_FOR_nothing,       "spu_cntb",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_CNTB_0,           CODE_FOR_cntb_v16qi,    "spu_cntb_0",           B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_CNTB_1,           CODE_FOR_cntb_v16qi,    "spu_cntb_1",           B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_CNTLZ,            CODE_FOR_nothing,       "spu_cntlz",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_CNTLZ_0,          CODE_FOR_clzv4si2,      "spu_cntlz_0",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_CNTLZ_1,          CODE_FOR_clzv4si2,      "spu_cntlz_1",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_CNTLZ_2,          CODE_FOR_clzv4si2,      "spu_cntlz_2",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_GATHER,           CODE_FOR_nothing,       "spu_gather",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_GATHER_0,         CODE_FOR_spu_gb,        "spu_gather_0",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_GATHER_1,         CODE_FOR_spu_gb,        "spu_gather_1",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_GATHER_2,         CODE_FOR_spu_gbh,       "spu_gather_2",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_GATHER_3,         CODE_FOR_spu_gbh,       "spu_gather_3",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_GATHER_4,         CODE_FOR_spu_gbb,       "spu_gather_4",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_GATHER_5,         CODE_FOR_spu_gbb,       "spu_gather_5",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_GATHER_6,         CODE_FOR_spu_gb,        "spu_gather_6",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_MASKB,            CODE_FOR_nothing,       "spu_maskb",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MASKB_0,          CODE_FOR_spu_fsmb,      "spu_maskb_0",          B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_MASKB_1,          CODE_FOR_spu_fsmb,      "spu_maskb_1",          B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_MASKB_2,          CODE_FOR_spu_fsmb,      "spu_maskb_2",          B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_MASKB_3,          CODE_FOR_spu_fsmb,      "spu_maskb_3",          B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_MASKH,            CODE_FOR_nothing,       "spu_maskh",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MASKH_0,          CODE_FOR_spu_fsmh,      "spu_maskh_0",          B_INTERNAL, _A2(SPU_BTI_UV8HI,  SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_MASKH_1,          CODE_FOR_spu_fsmh,      "spu_maskh_1",          B_INTERNAL, _A2(SPU_BTI_UV8HI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_MASKH_2,          CODE_FOR_spu_fsmh,      "spu_maskh_2",          B_INTERNAL, _A2(SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_MASKH_3,          CODE_FOR_spu_fsmh,      "spu_maskh_3",          B_INTERNAL, _A2(SPU_BTI_UV8HI,  SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_MASKH_4,          CODE_FOR_spu_fsmh,      "spu_maskh_4",          B_INTERNAL, _A2(SPU_BTI_UV8HI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_MASKH_5,          CODE_FOR_spu_fsmh,      "spu_maskh_5",          B_INTERNAL, _A2(SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_MASKW,            CODE_FOR_nothing,       "spu_maskw",            B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_MASKW_0,          CODE_FOR_spu_fsm,       "spu_maskw_0",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_MASKW_1,          CODE_FOR_spu_fsm,       "spu_maskw_1",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_MASKW_2,          CODE_FOR_spu_fsm,       "spu_maskw_2",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_MASKW_3,          CODE_FOR_spu_fsm,       "spu_maskw_3",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_MASKW_4,          CODE_FOR_spu_fsm,       "spu_maskw_4",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_MASKW_5,          CODE_FOR_spu_fsm,       "spu_maskw_5",          B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_SEL,              CODE_FOR_nothing,       "spu_sel",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SEL_0,            CODE_FOR_selb,          "spu_sel_0",            B_INTERNAL, _A4(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_SEL_1,            CODE_FOR_selb,          "spu_sel_1",            B_INTERNAL, _A4(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_SEL_2,            CODE_FOR_selb,          "spu_sel_2",            B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SEL_3,            CODE_FOR_selb,          "spu_sel_3",            B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SEL_4,            CODE_FOR_selb,          "spu_sel_4",            B_INTERNAL, _A4(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_SEL_5,            CODE_FOR_selb,          "spu_sel_5",            B_INTERNAL, _A4(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_SEL_6,            CODE_FOR_selb,          "spu_sel_6",            B_INTERNAL, _A4(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SEL_7,            CODE_FOR_selb,          "spu_sel_7",            B_INTERNAL, _A4(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SEL_8,            CODE_FOR_selb,          "spu_sel_8",            B_INTERNAL, _A4(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SEL_9,            CODE_FOR_selb,          "spu_sel_9",            B_INTERNAL, _A4(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_SHUFFLE,          CODE_FOR_nothing,       "spu_shuffle",          B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SHUFFLE_0,        CODE_FOR_shufb,         "spu_shuffle_0",        B_INTERNAL, _A4(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_1,        CODE_FOR_shufb,         "spu_shuffle_1",        B_INTERNAL, _A4(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_2,        CODE_FOR_shufb,         "spu_shuffle_2",        B_INTERNAL, _A4(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_3,        CODE_FOR_shufb,         "spu_shuffle_3",        B_INTERNAL, _A4(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_4,        CODE_FOR_shufb,         "spu_shuffle_4",        B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_5,        CODE_FOR_shufb,         "spu_shuffle_5",        B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_6,        CODE_FOR_shufb,         "spu_shuffle_6",        B_INTERNAL, _A4(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_7,        CODE_FOR_shufb,         "spu_shuffle_7",        B_INTERNAL, _A4(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_8,        CODE_FOR_shufb,         "spu_shuffle_8",        B_INTERNAL, _A4(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_SHUFFLE_9,        CODE_FOR_shufb,         "spu_shuffle_9",        B_INTERNAL, _A4(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_AND,              CODE_FOR_nothing,       "spu_and",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_AND_0,            CODE_FOR_andv16qi3,     "spu_and_0",            B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_AND_1,            CODE_FOR_andv16qi3,     "spu_and_1",            B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_AND_2,            CODE_FOR_andv8hi3,      "spu_and_2",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_AND_3,            CODE_FOR_andv8hi3,      "spu_and_3",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_AND_4,            CODE_FOR_andv4si3,      "spu_and_4",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_AND_5,            CODE_FOR_andv4si3,      "spu_and_5",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_AND_6,            CODE_FOR_andv2di3,      "spu_and_6",            B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_AND_7,            CODE_FOR_andv2di3,      "spu_and_7",            B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_AND_8,            CODE_FOR_andv4si3,      "spu_and_8",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_AND_9,            CODE_FOR_andv2di3,      "spu_and_9",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_AND_10,           CODE_FOR_andv16qi3,     "spu_and_10",           B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_AND_11,           CODE_FOR_andv16qi3,     "spu_and_11",           B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_AND_12,           CODE_FOR_andv8hi3,      "spu_and_12",           B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_AND_13,           CODE_FOR_andv8hi3,      "spu_and_13",           B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_AND_14,           CODE_FOR_andv4si3,      "spu_and_14",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_AND_15,           CODE_FOR_andv4si3,      "spu_and_15",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_ANDC,             CODE_FOR_nothing,       "spu_andc",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_ANDC_0,           CODE_FOR_andc_v2di,     "spu_andc_0",           B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_ANDC_1,           CODE_FOR_andc_v2di,     "spu_andc_1",           B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_ANDC_2,           CODE_FOR_andc_v4si,     "spu_andc_2",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_ANDC_3,           CODE_FOR_andc_v4si,     "spu_andc_3",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_ANDC_4,           CODE_FOR_andc_v8hi,     "spu_andc_4",           B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_ANDC_5,           CODE_FOR_andc_v8hi,     "spu_andc_5",           B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_ANDC_6,           CODE_FOR_andc_v16qi,    "spu_andc_6",           B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_ANDC_7,           CODE_FOR_andc_v16qi,    "spu_andc_7",           B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_ANDC_8,           CODE_FOR_andc_v4si,     "spu_andc_8",           B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_ANDC_9,           CODE_FOR_andc_v2di,     "spu_andc_9",           B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_EQV,              CODE_FOR_nothing,       "spu_eqv",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_EQV_0,            CODE_FOR_eqv_v2di,      "spu_eqv_0",            B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_EQV_1,            CODE_FOR_eqv_v2di,      "spu_eqv_1",            B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_EQV_2,            CODE_FOR_eqv_v4si,      "spu_eqv_2",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_EQV_3,            CODE_FOR_eqv_v4si,      "spu_eqv_3",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_EQV_4,            CODE_FOR_eqv_v8hi,      "spu_eqv_4",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_EQV_5,            CODE_FOR_eqv_v8hi,      "spu_eqv_5",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_EQV_6,            CODE_FOR_eqv_v16qi,     "spu_eqv_6",            B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_EQV_7,            CODE_FOR_eqv_v16qi,     "spu_eqv_7",            B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_EQV_8,            CODE_FOR_eqv_v4si,      "spu_eqv_8",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_EQV_9,            CODE_FOR_eqv_v2di,      "spu_eqv_9",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_NAND,             CODE_FOR_nothing,       "spu_nand",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_NAND_0,           CODE_FOR_nand_v2di,     "spu_nand_0",           B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_NAND_1,           CODE_FOR_nand_v2di,     "spu_nand_1",           B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_NAND_2,           CODE_FOR_nand_v4si,     "spu_nand_2",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_NAND_3,           CODE_FOR_nand_v4si,     "spu_nand_3",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_NAND_4,           CODE_FOR_nand_v8hi,     "spu_nand_4",           B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_NAND_5,           CODE_FOR_nand_v8hi,     "spu_nand_5",           B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_NAND_6,           CODE_FOR_nand_v16qi,    "spu_nand_6",           B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_NAND_7,           CODE_FOR_nand_v16qi,    "spu_nand_7",           B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_NAND_8,           CODE_FOR_nand_v4si,     "spu_nand_8",           B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_NAND_9,           CODE_FOR_nand_v2di,     "spu_nand_9",           B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_NOR,              CODE_FOR_nothing,       "spu_nor",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_NOR_0,            CODE_FOR_nor_v2di,      "spu_nor_0",            B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_NOR_1,            CODE_FOR_nor_v2di,      "spu_nor_1",            B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_NOR_2,            CODE_FOR_nor_v4si,      "spu_nor_2",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_NOR_3,            CODE_FOR_nor_v4si,      "spu_nor_3",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_NOR_4,            CODE_FOR_nor_v8hi,      "spu_nor_4",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_NOR_5,            CODE_FOR_nor_v8hi,      "spu_nor_5",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_NOR_6,            CODE_FOR_nor_v16qi,     "spu_nor_6",            B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_NOR_7,            CODE_FOR_nor_v16qi,     "spu_nor_7",            B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_NOR_8,            CODE_FOR_nor_v4si,      "spu_nor_8",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_NOR_9,            CODE_FOR_nor_v2di,      "spu_nor_9",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_OR,               CODE_FOR_nothing,       "spu_or",               B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_OR_0,             CODE_FOR_iorv16qi3,     "spu_or_0",             B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_OR_1,             CODE_FOR_iorv16qi3,     "spu_or_1",             B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_OR_2,             CODE_FOR_iorv8hi3,      "spu_or_2",             B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_OR_3,             CODE_FOR_iorv8hi3,      "spu_or_3",             B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_OR_4,             CODE_FOR_iorv4si3,      "spu_or_4",             B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_OR_5,             CODE_FOR_iorv4si3,      "spu_or_5",             B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_OR_6,             CODE_FOR_iorv2di3,      "spu_or_6",             B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_OR_7,             CODE_FOR_iorv2di3,      "spu_or_7",             B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_OR_8,             CODE_FOR_iorv4si3,      "spu_or_8",             B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_OR_9,             CODE_FOR_iorv2di3,      "spu_or_9",             B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_OR_10,            CODE_FOR_iorv16qi3,     "spu_or_10",            B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_OR_11,            CODE_FOR_iorv16qi3,     "spu_or_11",            B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_OR_12,            CODE_FOR_iorv8hi3,      "spu_or_12",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_OR_13,            CODE_FOR_iorv8hi3,      "spu_or_13",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_OR_14,            CODE_FOR_iorv4si3,      "spu_or_14",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_OR_15,            CODE_FOR_iorv4si3,      "spu_or_15",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_ORC,              CODE_FOR_nothing,       "spu_orc",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_ORC_0,            CODE_FOR_orc_v2di,      "spu_orc_0",            B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_ORC_1,            CODE_FOR_orc_v2di,      "spu_orc_1",            B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_ORC_2,            CODE_FOR_orc_v4si,      "spu_orc_2",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_ORC_3,            CODE_FOR_orc_v4si,      "spu_orc_3",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_ORC_4,            CODE_FOR_orc_v8hi,      "spu_orc_4",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_ORC_5,            CODE_FOR_orc_v8hi,      "spu_orc_5",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_ORC_6,            CODE_FOR_orc_v16qi,     "spu_orc_6",            B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_ORC_7,            CODE_FOR_orc_v16qi,     "spu_orc_7",            B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_ORC_8,            CODE_FOR_orc_v4si,      "spu_orc_8",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_ORC_9,            CODE_FOR_orc_v2di,      "spu_orc_9",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_ORX,              CODE_FOR_nothing,       "spu_orx",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_ORX_0,            CODE_FOR_spu_orx,       "spu_orx_0",            B_INTERNAL, _A2(SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_ORX_1,            CODE_FOR_spu_orx,       "spu_orx_1",            B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_XOR,              CODE_FOR_nothing,       "spu_xor",              B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_XOR_0,            CODE_FOR_xorv16qi3,     "spu_xor_0",            B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UV16QI))
+DEF_BUILTIN (SPU_XOR_1,            CODE_FOR_xorv16qi3,     "spu_xor_1",            B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_V16QI))
+DEF_BUILTIN (SPU_XOR_2,            CODE_FOR_xorv8hi3,      "spu_xor_2",            B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_XOR_3,            CODE_FOR_xorv8hi3,      "spu_xor_3",            B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_XOR_4,            CODE_FOR_xorv4si3,      "spu_xor_4",            B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_XOR_5,            CODE_FOR_xorv4si3,      "spu_xor_5",            B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_XOR_6,            CODE_FOR_xorv2di3,      "spu_xor_6",            B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UV2DI))
+DEF_BUILTIN (SPU_XOR_7,            CODE_FOR_xorv2di3,      "spu_xor_7",            B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_V2DI))
+DEF_BUILTIN (SPU_XOR_8,            CODE_FOR_xorv4si3,      "spu_xor_8",            B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_V4SF))
+DEF_BUILTIN (SPU_XOR_9,            CODE_FOR_xorv2di3,      "spu_xor_9",            B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_V2DF))
+DEF_BUILTIN (SPU_XOR_10,           CODE_FOR_xorv16qi3,     "spu_xor_10",           B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_XOR_11,           CODE_FOR_xorv16qi3,     "spu_xor_11",           B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_XOR_12,           CODE_FOR_xorv8hi3,      "spu_xor_12",           B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_XOR_13,           CODE_FOR_xorv8hi3,      "spu_xor_13",           B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_XOR_14,           CODE_FOR_xorv4si3,      "spu_xor_14",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_XOR_15,           CODE_FOR_xorv4si3,      "spu_xor_15",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RL,               CODE_FOR_nothing,       "spu_rl",               B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RL_0,             CODE_FOR_rotlv8hi3,     "spu_rl_0",             B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_RL_1,             CODE_FOR_rotlv8hi3,     "spu_rl_1",             B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_RL_2,             CODE_FOR_rotlv4si3,     "spu_rl_2",             B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_RL_3,             CODE_FOR_rotlv4si3,     "spu_rl_3",             B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_RL_4,             CODE_FOR_rotlv8hi3,     "spu_rl_4",             B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_RL_5,             CODE_FOR_rotlv8hi3,     "spu_rl_5",             B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_RL_6,             CODE_FOR_rotlv4si3,     "spu_rl_6",             B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RL_7,             CODE_FOR_rotlv4si3,     "spu_rl_7",             B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW,             CODE_FOR_nothing,       "spu_rlqw",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLQW_0,           CODE_FOR_rotqbi_ti,     "spu_rlqw_0",           B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_1,           CODE_FOR_rotqbi_ti,     "spu_rlqw_1",           B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_2,           CODE_FOR_rotqbi_ti,     "spu_rlqw_2",           B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_3,           CODE_FOR_rotqbi_ti,     "spu_rlqw_3",           B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_4,           CODE_FOR_rotqbi_ti,     "spu_rlqw_4",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_5,           CODE_FOR_rotqbi_ti,     "spu_rlqw_5",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_6,           CODE_FOR_rotqbi_ti,     "spu_rlqw_6",           B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_7,           CODE_FOR_rotqbi_ti,     "spu_rlqw_7",           B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_8,           CODE_FOR_rotqbi_ti,     "spu_rlqw_8",           B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQW_9,           CODE_FOR_rotqbi_ti,     "spu_rlqw_9",           B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE,         CODE_FOR_nothing,       "spu_rlqwbyte",         B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLQWBYTE_0,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_0",       B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_1,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_1",       B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_2,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_2",       B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_3,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_3",       B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_4,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_4",       B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_5,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_5",       B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_6,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_6",       B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_7,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_7",       B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_8,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_8",       B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTE_9,       CODE_FOR_rotqby_ti,     "spu_rlqwbyte_9",       B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC,       CODE_FOR_nothing,       "spu_rlqwbytebc",       B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLQWBYTEBC_0,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_0",     B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_1,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_1",     B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_2,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_2",     B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_3,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_3",     B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_4,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_4",     B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_5,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_5",     B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_6,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_6",     B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_7,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_7",     B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_8,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_8",     B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLQWBYTEBC_9,     CODE_FOR_rotqbybi_ti,   "spu_rlqwbytebc_9",     B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASK,           CODE_FOR_nothing,       "spu_rlmask",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLMASK_0,         CODE_FOR_rotm_v8hi,     "spu_rlmask_0",         B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_RLMASK_1,         CODE_FOR_rotm_v8hi,     "spu_rlmask_1",         B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_RLMASK_2,         CODE_FOR_rotm_v4si,     "spu_rlmask_2",         B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_RLMASK_3,         CODE_FOR_rotm_v4si,     "spu_rlmask_3",         B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_RLMASK_4,         CODE_FOR_rotm_v8hi,     "spu_rlmask_4",         B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASK_5,         CODE_FOR_rotm_v8hi,     "spu_rlmask_5",         B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASK_6,         CODE_FOR_rotm_v4si,     "spu_rlmask_6",         B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASK_7,         CODE_FOR_rotm_v4si,     "spu_rlmask_7",         B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKA,          CODE_FOR_nothing,       "spu_rlmaska",          B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLMASKA_0,        CODE_FOR_rotma_v8hi,    "spu_rlmaska_0",        B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_RLMASKA_1,        CODE_FOR_rotma_v8hi,    "spu_rlmaska_1",        B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_V8HI))
+DEF_BUILTIN (SPU_RLMASKA_2,        CODE_FOR_rotma_v4si,    "spu_rlmaska_2",        B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_RLMASKA_3,        CODE_FOR_rotma_v4si,    "spu_rlmaska_3",        B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_V4SI))
+DEF_BUILTIN (SPU_RLMASKA_4,        CODE_FOR_rotma_v8hi,    "spu_rlmaska_4",        B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKA_5,        CODE_FOR_rotma_v8hi,    "spu_rlmaska_5",        B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKA_6,        CODE_FOR_rotma_v4si,    "spu_rlmaska_6",        B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKA_7,        CODE_FOR_rotma_v4si,    "spu_rlmaska_7",        B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW,         CODE_FOR_nothing,       "spu_rlmaskqw",         B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLMASKQW_0,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_0",       B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_1,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_1",       B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_2,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_2",       B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_3,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_3",       B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_4,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_4",       B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_5,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_5",       B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_6,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_6",       B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_7,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_7",       B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_8,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_8",       B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQW_9,       CODE_FOR_rotqmbi_ti,    "spu_rlmaskqw_9",       B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE,     CODE_FOR_nothing,       "spu_rlmaskqwbyte",     B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_0,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_0",   B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_1,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_1",   B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_2,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_2",   B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_3,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_3",   B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_4,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_4",   B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_5,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_5",   B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_6,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_6",   B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_7,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_7",   B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_8,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_8",   B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTE_9,   CODE_FOR_rotqmby_ti,    "spu_rlmaskqwbyte_9",   B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC,   CODE_FOR_nothing,       "spu_rlmaskqwbytebc",   B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_0, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_0", B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_1, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_1", B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_2, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_2", B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_3, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_3", B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_4, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_4", B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_5, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_5", B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_6, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_6", B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_7, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_7", B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_8, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_8", B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_RLMASKQWBYTEBC_9, CODE_FOR_rotqmbybi_ti,  "spu_rlmaskqwbytebc_9", B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_SL,               CODE_FOR_nothing,       "spu_sl",               B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SL_0,             CODE_FOR_ashlv8hi3,     "spu_sl_0",             B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_SL_1,             CODE_FOR_ashlv8hi3,     "spu_sl_1",             B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_UV8HI))
+DEF_BUILTIN (SPU_SL_2,             CODE_FOR_ashlv4si3,     "spu_sl_2",             B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SL_3,             CODE_FOR_ashlv4si3,     "spu_sl_3",             B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_UV4SI))
+DEF_BUILTIN (SPU_SL_4,             CODE_FOR_ashlv8hi3,     "spu_sl_4",             B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SL_5,             CODE_FOR_ashlv8hi3,     "spu_sl_5",             B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SL_6,             CODE_FOR_ashlv4si3,     "spu_sl_6",             B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SL_7,             CODE_FOR_ashlv4si3,     "spu_sl_7",             B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW,             CODE_FOR_nothing,       "spu_slqw",             B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SLQW_0,           CODE_FOR_shlqbi_ti,     "spu_slqw_0",           B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_1,           CODE_FOR_shlqbi_ti,     "spu_slqw_1",           B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_2,           CODE_FOR_shlqbi_ti,     "spu_slqw_2",           B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_3,           CODE_FOR_shlqbi_ti,     "spu_slqw_3",           B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_4,           CODE_FOR_shlqbi_ti,     "spu_slqw_4",           B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_5,           CODE_FOR_shlqbi_ti,     "spu_slqw_5",           B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_6,           CODE_FOR_shlqbi_ti,     "spu_slqw_6",           B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_7,           CODE_FOR_shlqbi_ti,     "spu_slqw_7",           B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_8,           CODE_FOR_shlqbi_ti,     "spu_slqw_8",           B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQW_9,           CODE_FOR_shlqbi_ti,     "spu_slqw_9",           B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE,         CODE_FOR_nothing,       "spu_slqwbyte",         B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SLQWBYTE_0,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_0",       B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_1,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_1",       B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_2,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_2",       B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_3,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_3",       B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_4,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_4",       B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_5,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_5",       B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_6,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_6",       B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_7,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_7",       B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_8,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_8",       B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTE_9,       CODE_FOR_shlqby_ti,     "spu_slqwbyte_9",       B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC,       CODE_FOR_nothing,       "spu_slqwbytebc",       B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SLQWBYTEBC_0,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_0",     B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_V2DI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_1,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_1",     B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UV2DI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_2,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_2",     B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_V4SI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_3,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_3",     B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_4,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_4",     B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_V8HI,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_5,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_5",     B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UV8HI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_6,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_6",     B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_V16QI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_7,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_7",     B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UV16QI, SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_8,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_8",     B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_V4SF,   SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SLQWBYTEBC_9,     CODE_FOR_shlqbybi_ti,   "spu_slqwbytebc_9",     B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_V2DF,   SPU_BTI_UINTSI))
+
+DEF_BUILTIN (SPU_SPLATS,           CODE_FOR_nothing,       "spu_splats",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_SPLATS_0,         CODE_FOR_spu_splats,    "spu_splats_0",         B_INTERNAL, _A2(SPU_BTI_UV16QI, SPU_BTI_UINTQI))
+DEF_BUILTIN (SPU_SPLATS_1,         CODE_FOR_spu_splats,    "spu_splats_1",         B_INTERNAL, _A2(SPU_BTI_V16QI,  SPU_BTI_INTQI))
+DEF_BUILTIN (SPU_SPLATS_2,         CODE_FOR_spu_splats,    "spu_splats_2",         B_INTERNAL, _A2(SPU_BTI_UV8HI,  SPU_BTI_UINTHI))
+DEF_BUILTIN (SPU_SPLATS_3,         CODE_FOR_spu_splats,    "spu_splats_3",         B_INTERNAL, _A2(SPU_BTI_V8HI,   SPU_BTI_INTHI))
+DEF_BUILTIN (SPU_SPLATS_4,         CODE_FOR_spu_splats,    "spu_splats_4",         B_INTERNAL, _A2(SPU_BTI_UV4SI,  SPU_BTI_UINTSI))
+DEF_BUILTIN (SPU_SPLATS_5,         CODE_FOR_spu_splats,    "spu_splats_5",         B_INTERNAL, _A2(SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_SPLATS_6,         CODE_FOR_spu_splats,    "spu_splats_6",         B_INTERNAL, _A2(SPU_BTI_UV2DI,  SPU_BTI_UINTDI))
+DEF_BUILTIN (SPU_SPLATS_7,         CODE_FOR_spu_splats,    "spu_splats_7",         B_INTERNAL, _A2(SPU_BTI_V2DI,   SPU_BTI_INTDI))
+DEF_BUILTIN (SPU_SPLATS_8,         CODE_FOR_spu_splats,    "spu_splats_8",         B_INTERNAL, _A2(SPU_BTI_V4SF,   SPU_BTI_FLOAT))
+DEF_BUILTIN (SPU_SPLATS_9,         CODE_FOR_spu_splats,    "spu_splats_9",         B_INTERNAL, _A2(SPU_BTI_V2DF,   SPU_BTI_DOUBLE))
+DEF_BUILTIN (SPU_EXTRACT,          CODE_FOR_nothing,       "spu_extract",          B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_EXTRACT_0,        CODE_FOR_spu_extract,   "spu_extract_0",        B_INTERNAL, _A3(SPU_BTI_UINTQI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_1,        CODE_FOR_spu_extract,   "spu_extract_1",        B_INTERNAL, _A3(SPU_BTI_INTQI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_2,        CODE_FOR_spu_extract,   "spu_extract_2",        B_INTERNAL, _A3(SPU_BTI_UINTHI, SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_3,        CODE_FOR_spu_extract,   "spu_extract_3",        B_INTERNAL, _A3(SPU_BTI_INTHI,  SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_4,        CODE_FOR_spu_extract,   "spu_extract_4",        B_INTERNAL, _A3(SPU_BTI_UINTSI, SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_5,        CODE_FOR_spu_extract,   "spu_extract_5",        B_INTERNAL, _A3(SPU_BTI_INTSI,  SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_6,        CODE_FOR_spu_extract,   "spu_extract_6",        B_INTERNAL, _A3(SPU_BTI_UINTDI, SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_7,        CODE_FOR_spu_extract,   "spu_extract_7",        B_INTERNAL, _A3(SPU_BTI_INTDI,  SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_8,        CODE_FOR_spu_extract,   "spu_extract_8",        B_INTERNAL, _A3(SPU_BTI_FLOAT,  SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_EXTRACT_9,        CODE_FOR_spu_extract,   "spu_extract_9",        B_INTERNAL, _A3(SPU_BTI_DOUBLE, SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT,           CODE_FOR_nothing,       "spu_insert",           B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_INSERT_0,         CODE_FOR_spu_insert,    "spu_insert_0",         B_INTERNAL, _A4(SPU_BTI_UV16QI, SPU_BTI_UINTQI, SPU_BTI_UV16QI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_1,         CODE_FOR_spu_insert,    "spu_insert_1",         B_INTERNAL, _A4(SPU_BTI_V16QI,  SPU_BTI_INTQI,  SPU_BTI_V16QI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_2,         CODE_FOR_spu_insert,    "spu_insert_2",         B_INTERNAL, _A4(SPU_BTI_UV8HI,  SPU_BTI_UINTHI, SPU_BTI_UV8HI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_3,         CODE_FOR_spu_insert,    "spu_insert_3",         B_INTERNAL, _A4(SPU_BTI_V8HI,   SPU_BTI_INTHI,  SPU_BTI_V8HI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_4,         CODE_FOR_spu_insert,    "spu_insert_4",         B_INTERNAL, _A4(SPU_BTI_UV4SI,  SPU_BTI_UINTSI, SPU_BTI_UV4SI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_5,         CODE_FOR_spu_insert,    "spu_insert_5",         B_INTERNAL, _A4(SPU_BTI_V4SI,   SPU_BTI_INTSI,  SPU_BTI_V4SI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_6,         CODE_FOR_spu_insert,    "spu_insert_6",         B_INTERNAL, _A4(SPU_BTI_UV2DI,  SPU_BTI_UINTDI, SPU_BTI_UV2DI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_7,         CODE_FOR_spu_insert,    "spu_insert_7",         B_INTERNAL, _A4(SPU_BTI_V2DI,   SPU_BTI_INTDI,  SPU_BTI_V2DI,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_8,         CODE_FOR_spu_insert,    "spu_insert_8",         B_INTERNAL, _A4(SPU_BTI_V4SF,   SPU_BTI_FLOAT,  SPU_BTI_V4SF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_INSERT_9,         CODE_FOR_spu_insert,    "spu_insert_9",         B_INTERNAL, _A4(SPU_BTI_V2DF,   SPU_BTI_DOUBLE, SPU_BTI_V2DF,   SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE,          CODE_FOR_nothing,       "spu_promote",          B_OVERLOAD, _A1(SPU_BTI_VOID))
+DEF_BUILTIN (SPU_PROMOTE_0,        CODE_FOR_spu_promote,   "spu_promote_0",        B_INTERNAL, _A3(SPU_BTI_UV16QI, SPU_BTI_UINTQI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_1,        CODE_FOR_spu_promote,   "spu_promote_1",        B_INTERNAL, _A3(SPU_BTI_V16QI,  SPU_BTI_INTQI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_2,        CODE_FOR_spu_promote,   "spu_promote_2",        B_INTERNAL, _A3(SPU_BTI_UV8HI,  SPU_BTI_UINTHI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_3,        CODE_FOR_spu_promote,   "spu_promote_3",        B_INTERNAL, _A3(SPU_BTI_V8HI,   SPU_BTI_INTHI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_4,        CODE_FOR_spu_promote,   "spu_promote_4",        B_INTERNAL, _A3(SPU_BTI_UV4SI,  SPU_BTI_UINTSI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_5,        CODE_FOR_spu_promote,   "spu_promote_5",        B_INTERNAL, _A3(SPU_BTI_V4SI,   SPU_BTI_INTSI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_6,        CODE_FOR_spu_promote,   "spu_promote_6",        B_INTERNAL, _A3(SPU_BTI_UV2DI,  SPU_BTI_UINTDI, SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_7,        CODE_FOR_spu_promote,   "spu_promote_7",        B_INTERNAL, _A3(SPU_BTI_V2DI,   SPU_BTI_INTDI,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_8,        CODE_FOR_spu_promote,   "spu_promote_8",        B_INTERNAL, _A3(SPU_BTI_V4SF,   SPU_BTI_FLOAT,  SPU_BTI_INTSI))
+DEF_BUILTIN (SPU_PROMOTE_9,        CODE_FOR_spu_promote,   "spu_promote_9",        B_INTERNAL, _A3(SPU_BTI_V2DF,   SPU_BTI_DOUBLE, SPU_BTI_INTSI))
+
+/* We need something that is not B_INTERNAL as a sentinal. */
+
+/* These are for the convenience of imlpemnting fma() in the standard
+   libraries. */
+DEF_BUILTIN (SCALAR_FMA,           CODE_FOR_fma_sf,        "fmas",                 B_INSN,     _A4(SPU_BTI_FLOAT,  SPU_BTI_FLOAT, SPU_BTI_FLOAT, SPU_BTI_FLOAT))
+DEF_BUILTIN (SCALAR_DFMA,          CODE_FOR_fma_df,        "dfmas",                B_INSN,     _A4(SPU_BTI_DOUBLE, SPU_BTI_DOUBLE, SPU_BTI_DOUBLE, SPU_BTI_DOUBLE))
+
+DEF_BUILTIN (SPU_ALIGN_HINT,       CODE_FOR_spu_align_hint,"spu_align_hint",       B_INSN,     _A4(SPU_BTI_VOID,   SPU_BTI_PTR,    SPU_BTI_7,      SPU_BTI_7))
+#undef _A1
+#undef _A2
+#undef _A3
+#undef _A4
diff --git a/gcc/config/spu/spu-builtins.h b/gcc/config/spu/spu-builtins.h
new file mode 100644 (file)
index 0000000..4eb2d58
--- /dev/null
@@ -0,0 +1,120 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+\f
+/* built-ins */
+
+enum spu_builtin_type_index
+{
+  SPU_BTI_END_OF_PARAMS,
+
+  /* We create new type nodes for these. */
+  SPU_BTI_V16QI,
+  SPU_BTI_V8HI,
+  SPU_BTI_V4SI,
+  SPU_BTI_V2DI,
+  SPU_BTI_V4SF,
+  SPU_BTI_V2DF,
+  SPU_BTI_UV16QI,
+  SPU_BTI_UV8HI,
+  SPU_BTI_UV4SI,
+  SPU_BTI_UV2DI,
+
+  /* A 16-byte type. (Implemented with V16QI_type_node) */
+  SPU_BTI_QUADWORD,
+
+  /* These all correspond to intSI_type_node */
+  SPU_BTI_7,
+  SPU_BTI_S7,
+  SPU_BTI_U7,
+  SPU_BTI_S10,
+  SPU_BTI_S10_4,
+  SPU_BTI_U14,
+  SPU_BTI_16,
+  SPU_BTI_S16,
+  SPU_BTI_S16_2,
+  SPU_BTI_U16,
+  SPU_BTI_U16_2,
+  SPU_BTI_U18,
+
+  /* These correspond to the standard types */
+  SPU_BTI_INTQI, 
+  SPU_BTI_INTHI, 
+  SPU_BTI_INTSI, 
+  SPU_BTI_INTDI, 
+
+  SPU_BTI_UINTQI,
+  SPU_BTI_UINTHI,
+  SPU_BTI_UINTSI,
+  SPU_BTI_UINTDI,
+
+  SPU_BTI_FLOAT, 
+  SPU_BTI_DOUBLE,
+
+  SPU_BTI_VOID,   
+  SPU_BTI_PTR,   
+
+  SPU_BTI_MAX
+};
+
+#define V16QI_type_node               (spu_builtin_types[SPU_BTI_V16QI])
+#define V8HI_type_node                (spu_builtin_types[SPU_BTI_V8HI])
+#define V4SI_type_node                (spu_builtin_types[SPU_BTI_V4SI])
+#define V2DI_type_node                (spu_builtin_types[SPU_BTI_V2DI])
+#define V4SF_type_node                (spu_builtin_types[SPU_BTI_V4SF])
+#define V2DF_type_node                (spu_builtin_types[SPU_BTI_V2DF])
+#define unsigned_V16QI_type_node      (spu_builtin_types[SPU_BTI_UV16QI])
+#define unsigned_V8HI_type_node       (spu_builtin_types[SPU_BTI_UV8HI])
+#define unsigned_V4SI_type_node       (spu_builtin_types[SPU_BTI_UV4SI])
+#define unsigned_V2DI_type_node       (spu_builtin_types[SPU_BTI_UV2DI])
+
+extern GTY(()) tree spu_builtin_types[SPU_BTI_MAX];
+
+/* Some builtins require special handling.  This enum differentiates. */
+enum spu_builtin_type {
+    B_INSN,
+    B_JUMP,
+    B_BISLED,
+    B_CALL,
+    B_HINT,
+    B_OVERLOAD, 
+    B_INTERNAL
+};
+
+typedef enum {
+#define DEF_BUILTIN(fcode, icode, name, type, params) fcode,
+#include "spu-builtins.def"
+#undef DEF_BUILTIN
+   NUM_SPU_BUILTINS
+} spu_function_code;
+
+struct spu_builtin_description {
+    spu_function_code fcode;
+    enum insn_code icode;
+    const char *name;
+    enum spu_builtin_type type;
+
+    /* The first element of parm is always the return type.  The rest
+     * are a zero terminated list of parameters. */
+    int parm[5];
+
+    tree fndecl;
+};
+
+extern GTY(()) struct spu_builtin_description spu_builtins[];
+
+
+
diff --git a/gcc/config/spu/spu-builtins.md b/gcc/config/spu/spu-builtins.md
new file mode 100644 (file)
index 0000000..9b9a21b
--- /dev/null
@@ -0,0 +1,872 @@
+;; Copyright (C) 2006 Free Software Foundation, Inc.
+
+;; This file is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 2 of the License, or (at your option) 
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file; see the file COPYING.  If not, write to the Free
+;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+
+;; This includes expands for all the intrinsics.
+;; spu_expand_builtin looks at the mode of match_operand.
+
+\f
+;; load/store
+
+(define_expand "spu_lqd"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+        (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
+                                (match_operand:SI 2 "spu_nonmem_operand" ""))
+                       (const_int -16))))]
+  ""
+  {
+    if (GET_CODE (operands[2]) == CONST_INT
+       && (INTVAL (operands[2]) & 15) != 0)
+      operands[2] = GEN_INT (INTVAL (operands[2]) & -16);
+    if (GET_CODE (operands[2]) != CONST_INT)
+      {
+       rtx op2 = operands[2];
+       operands[2] = force_reg (Pmode, operands[2]);
+       if (!ALIGNED_SYMBOL_REF_P (op2))
+         emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16)));
+      }
+  })
+
+(define_expand "spu_lqx"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+        (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
+                                 (match_operand:SI 2 "spu_reg_operand" ""))
+                        (const_int -16))))]
+  ""
+  "")
+
+(define_expand "spu_lqa"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+        (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "")
+                        (const_int -16))))]
+  ""
+  {
+    if (GET_CODE (operands[1]) == CONST_INT
+       && (INTVAL (operands[1]) & 15) != 0)
+      operands[1] = GEN_INT (INTVAL (operands[1]) & -16);
+  })
+
+(define_expand "spu_lqr"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+       (mem:TI (and:SI (match_operand:SI 1 "address_operand" "")
+                       (const_int -16))))]
+  ""
+  "")
+
+(define_expand "spu_stqd"
+  [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
+                                (match_operand:SI 2 "spu_nonmem_operand" ""))
+                       (const_int -16)))
+        (match_operand:TI 0 "spu_reg_operand" "r,r"))]
+  ""
+  {
+    if (GET_CODE (operands[2]) == CONST_INT
+       && (INTVAL (operands[2]) & 15) != 0)
+      operands[2] = GEN_INT (INTVAL (operands[2]) & -16);
+    if (GET_CODE (operands[2]) != CONST_INT)
+      {
+       rtx op2 = operands[2];
+       operands[2] = force_reg (Pmode, operands[2]);
+       if (!ALIGNED_SYMBOL_REF_P (op2))
+         emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16)));
+      }
+  })
+
+(define_expand "spu_stqx"
+  [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
+                                (match_operand:SI 2 "spu_reg_operand" ""))
+                       (const_int -16)))
+        (match_operand:TI 0 "spu_reg_operand" "r"))]
+  ""
+  "")
+
+(define_expand "spu_stqa"
+  [(set (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "")
+                       (const_int -16)))
+        (match_operand:TI 0 "spu_reg_operand" "r"))]
+  ""
+  {
+    if (GET_CODE (operands[1]) == CONST_INT
+       && (INTVAL (operands[1]) & 15) != 0)
+      operands[1] = GEN_INT (INTVAL (operands[1]) & -16);
+  })
+
+(define_expand "spu_stqr"
+    [(set (mem:TI (and:SI (match_operand:SI 1 "address_operand" "")
+                         (const_int -16)))
+         (match_operand:TI 0 "spu_reg_operand" ""))]
+  ""
+  "")
+
+\f
+;; generate control word
+
+(define_expand "spu_cbx"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+        (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
+                    (match_operand:SI 2 "spu_nonmem_operand" "")
+                    (const_int 1)] UNSPEC_CPAT))]
+  ""
+  "")
+
+(define_expand "spu_chx"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+        (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
+                    (match_operand:SI 2 "spu_nonmem_operand" "")
+                    (const_int 2)] UNSPEC_CPAT))]
+  ""
+  "")
+
+(define_expand "spu_cwx"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+        (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
+                    (match_operand:SI 2 "spu_nonmem_operand" "")
+                    (const_int 4)] UNSPEC_CPAT))]
+  ""
+  "")
+
+(define_expand "spu_cdx"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+        (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
+                    (match_operand:SI 2 "spu_nonmem_operand" "")
+                    (const_int 8)] UNSPEC_CPAT))]
+  ""
+  "")
+
+
+\f
+;; Constant formation
+
+(define_expand "spu_ilhu"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "")
+        (const_vector:V4SI [(match_operand:SI 1 "immediate_operand" "")]))]
+  ""
+  "{ emit_insn(gen_movv4si(operands[0], spu_const(V4SImode, (INTVAL(operands[1]) << 16))));
+     DONE;
+   }")
+
+\f
+;; integer subtract
+(define_expand "spu_sfh"
+  [(set (match_operand:V8HI 0 "spu_reg_operand" "")
+        (minus:V8HI (match_operand:V8HI 2 "spu_nonmem_operand" "")
+                    (match_operand:V8HI 1 "spu_reg_operand" "")))]
+  ""
+  "")
+
+(define_expand "spu_sf"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "")
+        (minus:V4SI (match_operand:V4SI 2 "spu_nonmem_operand" "")
+                    (match_operand:V4SI 1 "spu_reg_operand" "")))]
+  ""
+  "")
+
+(define_expand "spu_sfx"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "")
+        (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "")
+                     (match_operand:V4SI 1 "spu_reg_operand" "")
+                     (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_SFX))]
+  ""
+  "")
+
+(define_expand "spu_bg"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "")
+        (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "")
+                     (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_BG))]
+  ""
+  "")
+
+(define_expand "spu_bgx"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "")
+        (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "")
+                     (match_operand:V4SI 1 "spu_reg_operand" "")
+                     (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_BGX))]
+  ""
+  "")
+
+;; integer multiply
+(define_insn "spu_mpy"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
+        (mult:V4SI
+         (sign_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 1 "spu_reg_operand" "r,r")
+             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
+          (sign_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 2 "spu_arith_operand" "r,B")
+             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
+  ""
+  "@
+   mpy\t%0,%1,%2
+   mpyi\t%0,%1,%H2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpyu"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
+        (mult:V4SI
+         (zero_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 1 "spu_reg_operand" "r,r")
+             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
+          (zero_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 2 "spu_arith_operand" "r,B")
+             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
+  ""
+  "@
+   mpyu\t%0,%1,%2
+   mpyui\t%0,%1,%H2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpya"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (plus:V4SI
+         (mult:V4SI
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 1 "spu_reg_operand" "r")
+               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 2 "spu_reg_operand" "r")
+               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
+       (match_operand:V4SI 3 "spu_reg_operand" "r")))]
+  ""
+  "mpya\t%0,%1,%2,%3"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpyh"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (ashift:V4SI
+         (mult:V4SI
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 1 "spu_reg_operand" "r")
+               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 2 "spu_reg_operand" "r")
+               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
+         (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))]
+  ""
+  "mpyh\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpys"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (ashiftrt:V4SI
+         (mult:V4SI
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 1 "spu_reg_operand" "r")
+               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 2 "spu_reg_operand" "r")
+               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
+         (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))]
+  ""
+  "mpys\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpyhhu"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+       (mult:V4SI
+         (zero_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 1 "spu_reg_operand" "r")
+             (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
+         (zero_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 2 "spu_reg_operand" "r")
+             (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
+  ""
+  "mpyhhu\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpyhh"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+       (mult:V4SI
+         (sign_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 1 "spu_reg_operand" "r")
+             (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
+         (sign_extend:V4SI
+           (vec_select:V4HI
+             (match_operand:V8HI 2 "spu_reg_operand" "r")
+             (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
+  ""
+  "mpyhh\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpyhhau"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (plus:V4SI
+         (mult:V4SI
+           (zero_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 1 "spu_reg_operand" "r")
+               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
+           (zero_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 2 "spu_reg_operand" "r")
+               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))
+         (match_operand:V4SI 3 "spu_reg_operand" "0")))]
+  ""
+  "mpyhhau\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_mpyhha"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (plus:V4SI
+         (mult:V4SI
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 1 "spu_reg_operand" "r")
+               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
+           (sign_extend:V4SI
+             (vec_select:V4HI
+               (match_operand:V8HI 2 "spu_reg_operand" "r")
+               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))
+         (match_operand:V4SI 3 "spu_reg_operand" "0")))]
+  ""
+  "mpyhha\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+;; form select mask
+(define_insn "spu_fsmb"
+  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r,r")
+        (unspec:V16QI [(match_operand:SI 1 "spu_nonmem_operand" "r,MN")] UNSPEC_FSMB))]
+  ""
+  "@
+  fsmb\t%0,%1
+  fsmbi\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+(define_insn "spu_fsmh"
+  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
+        (unspec:V8HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSMH))]
+  ""
+  "fsmh\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+(define_insn "spu_fsm"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (unspec:V4SI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
+  ""
+  "fsm\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+
+;; gather bits
+(define_insn "spu_gbb"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (unspec:V4SI [(match_operand:V16QI 1 "spu_reg_operand" "r")] UNSPEC_GBB))]
+  ""
+  "gbb\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+(define_insn "spu_gbh"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (unspec:V4SI [(match_operand:V8HI 1 "spu_reg_operand" "r")] UNSPEC_GBH))]
+  ""
+  "gbh\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+(define_insn "spu_gb"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_GB))]
+  ""
+  "gb\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+;; misc byte operations
+(define_insn "spu_avgb"
+  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
+        (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")
+                      (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_AVGB))]
+  ""
+  "avgb\t%0,%1,%2"
+  [(set_attr "type" "fxb")])
+
+(define_insn "spu_absdb"
+  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
+        (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")
+                      (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_ABSDB))]
+  ""
+  "absdb\t%0,%1,%2"
+  [(set_attr "type" "fxb")])
+
+(define_insn "spu_sumb"
+  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
+        (unspec:V8HI [(match_operand:V16QI 1 "spu_reg_operand" "r")
+                     (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_SUMB))]
+  ""
+  "sumb\t%0,%1,%2"
+  [(set_attr "type" "fxb")])
+
+;; sign extend
+(define_insn "spu_xsbh"
+  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
+        (sign_extend:V8HI
+         (vec_select:V8QI
+           (match_operand:V16QI 1 "spu_reg_operand" "r")
+           (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
+                      (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
+  ""
+  "xsbh\t%0,%1")
+
+(define_insn "spu_xshw"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (sign_extend:V4SI
+         (vec_select:V4HI
+           (match_operand:V8HI 1 "spu_reg_operand" "r")
+           (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
+  ""
+  "xshw\t%0,%1")
+
+(define_insn "spu_xswd"
+  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
+        (sign_extend:V2DI
+         (vec_select:V2SI
+           (match_operand:V4SI 1 "spu_reg_operand" "r")
+           (parallel [(const_int 1)(const_int 3)]))))]
+  ""
+  "xswd\t%0,%1")
+
+;; or across
+
+(define_insn "spu_orx"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+       (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_ORX))]
+  ""
+  "orx\t%0,%1")
+
+
+;; compare & halt
+(define_insn "spu_heq"
+  [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
+                    (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HEQ)]
+  ""
+  "@
+  heq\t%0,%1
+  heqi\t%0,%1")
+
+(define_insn "spu_hgt"
+  [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
+                    (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HGT)]
+  ""
+  "@
+  hgt\t%0,%1
+  hgti\t%0,%1")
+
+(define_insn "spu_hlgt"
+  [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
+                    (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HLGT)]
+  ""
+  "@
+  hlgt\t%0,%1
+  hlgti\t%0,%1")
+
+;; branches
+
+;; The description below hides the fact that bisled conditionally
+;; executes the call depending on the value in channel 0.  This was 
+;; done so that the description would conform to the format of a call 
+;; insn.  Otherwise (if this were not part of call insn), the link 
+;; register, $lr, would not be saved/restored in the prologue/epilogue.
+
+(define_insn "spu_bisled"
+  [(parallel
+    [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
+            (const_int 0))
+     (clobber (reg:SI 0))
+     (clobber (reg:SI 130))
+     (use (match_operand:SI 1 "address_operand" ""))
+     (use (const_int 0))])]
+  ""
+  "bisled\t$lr,%0"
+  [(set_attr "type" "br")])
+
+(define_insn "spu_bisledd"
+  [(parallel
+    [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
+            (const_int 0))
+     (clobber (reg:SI 0))
+     (clobber (reg:SI 130))
+     (use (match_operand:SI 1 "address_operand" ""))
+     (use (const_int 1))])]
+  ""
+  "bisledd\t$lr,%0"
+  [(set_attr "type" "br")])
+
+(define_insn "spu_bislede"
+  [(parallel
+    [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
+            (const_int 0))
+     (clobber (reg:SI 0))
+     (clobber (reg:SI 130))
+     (use (match_operand:SI 1 "address_operand" ""))
+     (use (const_int 2))])]
+  ""
+  "bislede\t$lr,%0"
+  [(set_attr "type" "br")])
+
+;; float convert
+(define_insn "spu_csflt"
+  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
+       (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
+                     (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CSFLT ))]
+  ""
+  "csflt\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_cflts"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+       (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
+                      (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTS ))]
+  ""
+  "cflts\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_cuflt"
+  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
+       (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
+                     (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CUFLT ))]
+  ""
+  "cuflt\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "spu_cfltu"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+       (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
+                     (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTU ))]
+  ""
+  "cfltu\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_expand "spu_frds"
+   [(set (match_operand:V4SF 0 "spu_reg_operand" "")
+         (vec_select:V4SF
+          (vec_concat:V4SF
+            (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" ""))
+            (match_dup:V2SF 2))
+          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
+  ""
+  "operands[2] = spu_const(V2SFmode, 0);")
+
+(define_insn "_frds"
+   [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
+        (vec_select:V4SF
+         (vec_concat:V4SF
+           (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "r"))
+           (match_operand:V2SF 2 "vec_imm_operand" "i"))
+         (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
+  ""
+  "frds\t%0,%1"
+  [(set_attr "type" "fpd")])
+
+(define_insn "spu_fesd"
+  [(set (match_operand:V2DF 0 "spu_reg_operand" "=r")
+        (float_extend:V2DF
+         (vec_select:V2SF
+           (match_operand:V4SF 1 "spu_reg_operand" "r")
+             (parallel [(const_int 0)(const_int 2)]))))]
+  ""
+  "fesd\t%0,%1"
+  [(set_attr "type" "fpd")])
+
+;; control
+(define_insn "spu_stop"
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "M")] UNSPEC_STOP)]
+  ""
+  "stop\t%0"
+  [(set_attr "type" "br")])
+
+(define_insn "spu_stopd"
+  [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r")
+                    (match_operand:SI 1 "spu_reg_operand" "r")
+                    (match_operand:SI 2 "spu_reg_operand" "r")] UNSPEC_STOPD)]
+  ""
+  "stopd\t%0,%1,%2"
+  [(set_attr "type" "br")])
+
+;; interrupt disable/enable
+;; Register 131 is used exclusively for enabling/disabling interrupts.
+;; It is marked as a global reg and the instructions clobber mem, so it will
+;; not be incorrectly optimized.
+(define_expand "spu_idisable"
+  [(parallel
+    [(set (reg:INTR 131) (const_int 0))
+     (clobber (match_dup:SI 0))
+     (clobber (mem:BLK (scratch)))])]
+  ""
+  "operands[0] = gen_reg_rtx (SImode);")
+
+(define_expand "spu_ienable"
+  [(parallel
+    [(set (reg:INTR 131) (const_int 1))
+     (clobber (match_dup:SI 0))
+     (clobber (mem:BLK (scratch)))])]
+  ""
+  "operands[0] = gen_reg_rtx (SImode);")
+
+(define_insn "set_intr"
+  [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i"))
+   (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
+   (clobber (mem:BLK (scratch)))]
+  "! flag_pic"
+  "ila\t%0,.+8\;bi%I1\t%0"
+  [(set_attr "length" "8")
+   (set_attr "type" "multi0")])
+
+(define_insn "set_intr_pic"
+  [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i"))
+   (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
+   (clobber (mem:BLK (scratch)))]
+  "flag_pic"
+  "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0"
+  [(set_attr "length" "12")
+   (set_attr "type" "multi1")])
+
+(define_expand "movintrcc"
+  [(parallel
+    [(set (match_operand:INTR 0 "spu_reg_operand" "")
+         (if_then_else:INTR (match_operand 1 "branch_comparison_operator" "")
+                       (match_operand 3 "const_int_operand" "")
+                       (match_operand:INTR 2 "spu_reg_operand" "")))
+     (clobber (match_dup:SI 4))
+     (clobber (mem:BLK (scratch)))])]
+  ""
+  { /* We've swapped operands 2 and 3 in the pattern, reverse the
+       condition code too. */
+    PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
+    operands[4] = gen_reg_rtx (SImode);
+  })
+
+(define_insn "set_intr_cc"
+  [(set (reg:INTR 131)
+       (if_then_else:INTR
+         (match_operator 1 "branch_comparison_operator"
+           [(match_operand 2 "spu_reg_operand" "r")
+            (const_int 0)])
+         (match_operand:SI 3 "const_int_operand" "i")
+         (reg:INTR 131)))
+   (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
+   (clobber (mem:BLK (scratch)))]
+  "! flag_pic"
+  "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0"
+  [(set_attr "length" "8")
+   (set_attr "type" "multi0")])
+
+(define_insn "set_intr_cc_pic"
+  [(set (reg:INTR 131)
+       (if_then_else:INTR
+         (match_operator 1 "branch_comparison_operator"
+           [(match_operand 2 "spu_reg_operand" "r")
+            (const_int 0)])
+         (match_operand:SI 3 "const_int_operand" "i")
+         (reg:INTR 131)))
+   (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
+   (clobber (mem:BLK (scratch)))]
+  "flag_pic"
+  "brsl\t%0,.+4\;ai\t%0,%0,8\;%b2%b1z%I3\t%2,%0"
+  [(set_attr "length" "12")
+   (set_attr "type" "multi1")])
+
+(define_insn "set_intr_return"
+  [(set (reg:INTR 131) (match_operand 0 "const_int_operand" "i"))
+   (return)]
+  ""
+  "bi%I0\t$lr"
+  [(set_attr "type" "br")])
+
+(define_peephole2
+  [(parallel
+    [(set (reg:INTR 131) (match_operand 0 "const_int_operand"))
+     (clobber (match_operand:SI 1 "spu_reg_operand"))
+     (clobber (mem:BLK (scratch)))])
+   (use (reg:SI 0))
+   (return)]
+  ""
+  [(use (reg:SI 0))
+   (parallel
+    [(set (reg:INTR 131) (match_dup 0))
+     (return)])]
+  "")
+
+;; special purpose registers
+(define_insn "spu_fscrrd"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))]
+  ""
+  "fscrrd\t%0"
+  [(set_attr "type" "spr")])
+
+(define_insn "spu_fscrwr"
+  [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)]
+  ""
+  "fscrwr\t$0,%0"
+  [(set_attr "type" "spr")])
+
+(define_insn "spu_mfspr"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+        (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))]
+  ""
+  "mfspr\t%0,$sp%1"
+  [(set_attr "type" "spr")])
+
+(define_insn "spu_mtspr"
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
+                    (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)]
+  ""
+  "mtspr\t$sp%0,%1"
+  [(set_attr "type" "spr")])
+
+;; channels
+(define_expand "spu_rdch"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "")
+        (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))]
+  ""
+  "{
+    if (spu_safe_dma (INTVAL (operands[1])))
+      {
+        emit_insn (gen_spu_rdch_clobber (operands[0], operands[1]));
+        DONE;
+      }
+   }")
+
+(define_expand "spu_rchcnt"
+  [(set (match_operand:SI 0 "spu_reg_operand" "")
+        (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))]
+  ""
+  "{
+    if (spu_safe_dma (INTVAL (operands[1])))
+      {
+        emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1]));
+        DONE;
+      }
+   }")
+
+(define_expand "spu_wrch"
+   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "")
+                     (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)]
+   ""
+  "{
+    if (spu_safe_dma (INTVAL (operands[0])))
+      {
+        emit_insn (gen_spu_wrch_clobber (operands[0], operands[1]));
+        DONE;
+      }
+   }")
+
+(define_insn "spu_rdch_noclobber"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))]
+  ""
+  "rdch\t%0,$ch%1"
+  [(set_attr "type" "spr")])
+
+(define_insn "spu_rchcnt_noclobber"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+        (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))]
+  ""
+  "rchcnt\t%0,$ch%1"
+  [(set_attr "type" "spr")])
+
+(define_insn "spu_wrch_noclobber"
+   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
+                     (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)]
+   ""
+   "wrch\t$ch%0,%1"
+   [(set_attr "type" "spr")])
+
+(define_insn "spu_rdch_clobber"
+  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
+        (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))
+    (clobber (mem:BLK (scratch)))]
+  ""
+  "rdch\t%0,$ch%1"
+  [(set_attr "type" "spr")])
+
+(define_insn "spu_rchcnt_clobber"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+        (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))
+    (clobber (mem:BLK (scratch)))]
+  ""
+  "rchcnt\t%0,$ch%1"
+  [(set_attr "type" "spr")])
+
+(define_insn "spu_wrch_clobber"
+   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
+                     (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)
+    (clobber (mem:BLK (scratch)))]
+   ""
+   "wrch\t$ch%0,%1"
+   [(set_attr "type" "spr")])
+
+(define_expand "spu_splats" 
+  [(set (match_operand 0 "spu_reg_operand" "")
+        (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))]
+  ""
+  {
+    spu_builtin_splats(operands);
+    DONE;
+  })
+
+(define_expand "spu_extract"
+  [(set (match_operand 0 "spu_reg_operand" "")
+       (unspec [(match_operand 1 "spu_reg_operand" "")
+                (match_operand 2 "spu_nonmem_operand" "")] 0))]
+  ""
+  {
+    spu_builtin_extract (operands);
+    DONE;
+  })
+
+(define_expand "spu_insert"
+  [(set (match_operand 0 "spu_reg_operand" "")
+        (unspec [(match_operand 1 "spu_reg_operand" "")
+                 (match_operand 2 "spu_reg_operand" "")
+                 (match_operand:SI 3 "spu_nonmem_operand" "")] 0))] 
+  ""
+  {
+    spu_builtin_insert(operands);
+    DONE;
+  })
+
+(define_expand "spu_promote"
+  [(set (match_operand 0 "spu_reg_operand" "")
+        (unspec [(match_operand 1 "spu_reg_operand" "")
+                 (match_operand:SI 2 "immediate_operand" "")] 0))] 
+  ""
+  {
+    spu_builtin_promote(operands);
+    DONE;
+  })
+
+;; Currently doing nothing with this but expanding its args.
+(define_expand "spu_align_hint"
+  [(unspec [(match_operand:SI 0 "address_operand" "")
+            (match_operand:SI 1 "immediate_operand" "")
+            (match_operand:SI 2 "immediate_operand" "")] 0)]
+  ""
+  {
+     DONE;
+  })
+
diff --git a/gcc/config/spu/spu-c.c b/gcc/config/spu/spu-c.c
new file mode 100644 (file)
index 0000000..80a5701
--- /dev/null
@@ -0,0 +1,443 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "c-tree.h"
+#include "c-pragma.h"
+#include "function.h"
+#include "rtl.h"
+#include "expr.h"
+#include "errors.h"
+#include "tm_p.h"
+#include "langhooks.h"
+#include "insn-config.h"
+#include "insn-codes.h"
+#include "recog.h"
+#include "optabs.h"
+#include "spu-builtins.h"
+
+static rtx spu_expand_builtin_1 (struct spu_builtin_description *d,
+                                tree arglist, rtx target);
+static void spu_check_builtin_parm (struct spu_builtin_description *, rtx,
+                                   int);
+static void expand_builtin_args (struct spu_builtin_description *, tree, rtx,
+                                rtx[]);
+static rtx spu_force_reg (enum machine_mode mode, rtx op);
+
+/* Builtin types, data and prototypes. */
+struct spu_builtin_range
+{
+  int low, high;
+};
+
+static struct spu_builtin_range spu_builtin_range[] = {
+  {-0x40ll, 0x7fll},           /* SPU_BTI_7     */
+  {-0x40ll, 0x3fll},           /* SPU_BTI_S7    */
+  {0ll, 0x7fll},               /* SPU_BTI_U7    */
+  {-0x200ll, 0x1ffll},         /* SPU_BTI_S10   */
+  {-0x2000ll, 0x1fffll},       /* SPU_BTI_S10_4 */
+  {0ll, 0x3fffll},             /* SPU_BTI_U14   */
+  {-0x8000ll, 0xffffll},       /* SPU_BTI_16    */
+  {-0x8000ll, 0x7fffll},       /* SPU_BTI_S16   */
+  {-0x20000ll, 0x1ffffll},     /* SPU_BTI_S16_2 */
+  {0ll, 0xffffll},             /* SPU_BTI_U16   */
+  {0ll, 0x3ffffll},            /* SPU_BTI_U16_2 */
+  {0ll, 0x3ffffll},            /* SPU_BTI_U18   */
+};
+\f
+
+/* Helper for spu_resolve_overloaded_builtin.  */
+static tree
+spu_build_overload_builtin (tree fndecl, tree fnargs)
+{
+  tree param, param_type;
+  tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
+  tree arg, arglist = NULL_TREE;
+  tree val;
+
+  for (param = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), arg = fnargs;
+       param != void_list_node;
+       param = TREE_CHAIN (param), arg = TREE_CHAIN (arg))
+    {
+      gcc_assert (arg != NULL_TREE);
+      param_type = TREE_VALUE (param);
+      val = default_conversion (TREE_VALUE (arg));
+      val = fold_convert (param_type, val);
+
+      arglist = tree_cons (NULL_TREE, val, arglist);
+    }
+  gcc_assert (arg == NULL_TREE);
+  arglist = nreverse (arglist);
+
+  return fold_convert (ret_type, build_function_call_expr (fndecl, arglist));
+}
+
+/* target hook for resolve_overloaded_builtin(). Returns a function call
+   RTX if we can resolve the overloaded builtin */
+tree
+spu_resolve_overloaded_builtin (tree fndecl, tree fnargs)
+{
+  spu_function_code new_fcode, fcode =
+    DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
+  struct spu_builtin_description *desc;
+  tree match = NULL_TREE;
+
+  /* The vector types are not available if the backend is not initalized */
+  gcc_assert (!flag_preprocess_only);
+
+  desc = &spu_builtins[fcode];
+  if (desc->type != B_OVERLOAD)
+    return NULL_TREE;
+
+  /* Compare the signature of each internal builtin function with the
+     function arguments until a match is found. */
+
+  for (new_fcode = fcode + 1; spu_builtins[new_fcode].type == B_INTERNAL;
+       new_fcode++)
+    {
+      tree decl = spu_builtins[new_fcode].fndecl;
+      tree params = TYPE_ARG_TYPES (TREE_TYPE (decl));
+      tree arg, param;
+      int p;
+
+      for (param = params, arg = fnargs, p = 0;
+          param != void_list_node;
+          param = TREE_CHAIN (param), arg = TREE_CHAIN (arg), p++)
+       {
+         tree var, arg_type, param_type = TREE_VALUE (param);
+
+         if (!arg)
+           {
+             error ("insufficient arguments to overloaded function %s",
+                    desc->name);
+             return error_mark_node;
+           }
+
+         var = TREE_VALUE (arg);
+
+         if (TREE_CODE (var) == NON_LVALUE_EXPR)
+           var = TREE_OPERAND (var, 0);
+
+         if (TREE_CODE (var) == ERROR_MARK)
+           return NULL_TREE;   /* Let somebody else deal with the problem. */
+
+         arg_type = TREE_TYPE (var);
+
+         /* The intrinsics spec does not specify precisely how to
+            resolve generic intrinsics.  We require an exact match
+            for vector types and let C do it's usual parameter type
+            checking/promotions for scalar arguments, except for the
+            first argument of intrinsics which don't have a vector
+            parameter. */
+         if ((TREE_CODE (param_type) == VECTOR_TYPE
+              || ((fcode == SPU_SPLATS || fcode == SPU_PROMOTE
+                   || fcode == SPU_HCMPEQ || fcode == SPU_HCMPGT
+                   || fcode == SPU_MASKB || fcode == SPU_MASKH
+                   || fcode == SPU_MASKW) && p == 0))
+             && !comptypes (TYPE_MAIN_VARIANT (param_type),
+                            TYPE_MAIN_VARIANT (arg_type)))
+           break;
+       }
+      if (param == void_list_node)
+       {
+         if (arg)
+           {
+             error ("too many arguments to overloaded function %s",
+                    desc->name);
+             return error_mark_node;
+           }
+
+         match = decl;
+         break;
+       }
+    }
+
+  if (match == NULL_TREE)
+    {
+      error ("parameter list does not match a valid signature for %s()",
+            desc->name);
+      return error_mark_node;
+    }
+
+  return spu_build_overload_builtin (match, fnargs);
+}
+
+static void
+spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p)
+{
+  HOST_WIDE_INT v = 0;
+  int lsbits;
+  /* Check the range of immediate operands. */
+  if (p >= SPU_BTI_7 && p <= SPU_BTI_U18)
+    {
+      int range = p - SPU_BTI_7;
+      if (!CONSTANT_P (op)
+         || (GET_CODE (op) == CONST_INT
+             && (INTVAL (op) < spu_builtin_range[range].low
+                 || INTVAL (op) > spu_builtin_range[range].high)))
+       error ("%s expects an integer literal in the range [%d, %d].",
+              d->name,
+              spu_builtin_range[range].low, spu_builtin_range[range].high);
+
+      if (GET_CODE (op) == CONST
+         && (GET_CODE (XEXP (op, 0)) == PLUS
+             || GET_CODE (XEXP (op, 0)) == MINUS))
+       {
+         v = INTVAL (XEXP (XEXP (op, 0), 1));
+         op = XEXP (XEXP (op, 0), 0);
+       }
+      else if (GET_CODE (op) == CONST_INT)
+       v = INTVAL (op);
+
+      switch (p)
+       {
+       case SPU_BTI_S10_4:
+         lsbits = 4;
+         break;
+       case SPU_BTI_U16_2:
+         /* This is only used in lqa, and stqa.  Even though the insns
+            encode 16 bits of the address (all but the 2 least
+            significant), only 14 bits are used because it is masked to
+            be 16 byte aligned. */
+         lsbits = 4;
+         break;
+       case SPU_BTI_S16_2:
+         /* This is used for lqr and stqr. */
+         lsbits = 2;
+         break;
+       default:
+         lsbits = 0;
+       }
+
+      if (GET_CODE (op) == LABEL_REF
+         || (GET_CODE (op) == SYMBOL_REF
+             && SYMBOL_REF_FUNCTION_P (op))
+         || (INTVAL (op) & ((1 << lsbits) - 1)) != 0)
+       warning (0, "%d least significant bits of %s are ignored.", lsbits,
+                d->name);
+    }
+}
+
+static void
+expand_builtin_args (struct spu_builtin_description *d, tree arglist,
+                    rtx target, rtx ops[])
+{
+  enum insn_code icode = d->icode;
+  int i = 0;
+
+  /* Expand the arguments into rtl. */
+
+  if (d->parm[0] != SPU_BTI_VOID)
+    ops[i++] = target;
+
+  for (; i < insn_data[icode].n_operands; i++)
+    {
+      tree arg = TREE_VALUE (arglist);
+      if (arg == 0)
+       abort ();
+      ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, 0);
+      arglist = TREE_CHAIN (arglist);
+    }
+}
+
+static rtx
+spu_expand_builtin_1 (struct spu_builtin_description *d,
+                     tree arglist, rtx target)
+{
+  rtx pat;
+  rtx ops[8];
+  enum insn_code icode = d->icode;
+  enum machine_mode mode, tmode;
+  int i, p;
+  tree return_type;
+
+  /* Set up ops[] with values from arglist. */
+  expand_builtin_args (d, arglist, target, ops);
+
+  /* Handle the target operand which must be operand 0. */
+  i = 0;
+  if (d->parm[0] != SPU_BTI_VOID)
+    {
+
+      /* We prefer the mode specified for the match_operand otherwise
+         use the mode from the builtin function prototype. */
+      tmode = insn_data[d->icode].operand[0].mode;
+      if (tmode == VOIDmode)
+       tmode = TYPE_MODE (spu_builtin_types[d->parm[0]]);
+
+      /* Try to use target because not using it can lead to extra copies
+         and when we are using all of the registers extra copies leads
+         to extra spills.  */
+      if (target && GET_CODE (target) == REG && GET_MODE (target) == tmode)
+       ops[0] = target;
+      else
+       target = ops[0] = gen_reg_rtx (tmode);
+
+      if (!(*insn_data[icode].operand[0].predicate) (ops[0], tmode))
+       abort ();
+
+      i++;
+    }
+
+  /* Ignore align_hint, but still expand it's args in case they have
+     side effects. */
+  if (icode == CODE_FOR_spu_align_hint)
+    return 0;
+
+  /* Handle the rest of the operands. */
+  for (p = 1; i < insn_data[icode].n_operands; i++, p++)
+    {
+      if (insn_data[d->icode].operand[i].mode != VOIDmode)
+       mode = insn_data[d->icode].operand[i].mode;
+      else
+       mode = TYPE_MODE (spu_builtin_types[d->parm[i]]);
+
+      /* mode can be VOIDmode here for labels */
+
+      /* For specific intrinsics with an immediate operand, e.g.,
+         si_ai(), we sometimes need to convert the scalar argument to a
+         vector argument by splatting the scalar. */
+      if (VECTOR_MODE_P (mode)
+         && (GET_CODE (ops[i]) == CONST_INT
+             || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_INT
+             || GET_MODE_CLASS (GET_MODE (ops[i])) == MODE_FLOAT))
+       {
+         if (GET_CODE (ops[i]) == CONST_INT)
+           ops[i] = spu_const (mode, INTVAL (ops[i]));
+         else
+           {
+             rtx reg = gen_reg_rtx (mode);
+             enum machine_mode imode = GET_MODE_INNER (mode);
+             if (!spu_nonmem_operand (ops[i], GET_MODE (ops[i])))
+               ops[i] = force_reg (GET_MODE (ops[i]), ops[i]);
+             if (imode != GET_MODE (ops[i]))
+               ops[i] = convert_to_mode (imode, ops[i],
+                                         TYPE_UNSIGNED (spu_builtin_types
+                                                        [d->parm[i]]));
+             emit_insn (gen_spu_splats (reg, ops[i]));
+             ops[i] = reg;
+           }
+       }
+
+      if (!(*insn_data[icode].operand[i].predicate) (ops[i], mode))
+       ops[i] = spu_force_reg (mode, ops[i]);
+
+      spu_check_builtin_parm (d, ops[i], d->parm[p]);
+    }
+
+  switch (insn_data[icode].n_operands)
+    {
+    case 0:
+      pat = GEN_FCN (icode) (0);
+      break;
+    case 1:
+      pat = GEN_FCN (icode) (ops[0]);
+      break;
+    case 2:
+      pat = GEN_FCN (icode) (ops[0], ops[1]);
+      break;
+    case 3:
+      pat = GEN_FCN (icode) (ops[0], ops[1], ops[2]);
+      break;
+    case 4:
+      pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]);
+      break;
+    case 5:
+      pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4]);
+      break;
+    case 6:
+      pat = GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3], ops[4], ops[5]);
+      break;
+    default:
+      abort ();
+    }
+
+  if (!pat)
+    abort ();
+
+  if (d->type == B_CALL || d->type == B_BISLED)
+    emit_call_insn (pat);
+  else if (d->type == B_JUMP)
+    {
+      emit_jump_insn (pat);
+      emit_barrier ();
+    }
+  else
+    emit_insn (pat);
+
+  return_type = spu_builtin_types[d->parm[0]];
+  if (d->parm[0] != SPU_BTI_VOID
+      && GET_MODE (target) != TYPE_MODE (return_type))
+    {
+      /* target is the return value.  It should always be the mode of
+         the builtin function prototype. */
+      target = spu_force_reg (TYPE_MODE (return_type), target);
+    }
+
+  return target;
+}
+
+rtx
+spu_expand_builtin (tree exp,
+                   rtx target,
+                   rtx subtarget ATTRIBUTE_UNUSED,
+                   enum machine_mode mode ATTRIBUTE_UNUSED,
+                   int ignore ATTRIBUTE_UNUSED)
+{
+  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+  unsigned int fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
+  tree arglist = TREE_OPERAND (exp, 1);
+  struct spu_builtin_description *d;
+
+  if (fcode < NUM_SPU_BUILTINS)
+    {
+      d = &spu_builtins[fcode];
+
+      return spu_expand_builtin_1 (d, arglist, target);
+    }
+  abort ();
+}
+
+static rtx
+spu_force_reg (enum machine_mode mode, rtx op)
+{
+  rtx x, r;
+  if (GET_MODE (op) == VOIDmode || GET_MODE (op) == BLKmode)
+    {
+      if ((SCALAR_INT_MODE_P (mode) && GET_CODE (op) == CONST_INT)
+         || GET_MODE (op) == BLKmode)
+       return force_reg (mode, convert_to_mode (mode, op, 0));
+      abort ();
+    }
+
+  r = force_reg (GET_MODE (op), op);
+  if (GET_MODE_SIZE (GET_MODE (op)) == GET_MODE_SIZE (mode))
+    {
+      x = simplify_gen_subreg (mode, r, GET_MODE (op), 0);
+      if (x)
+       return x;
+    }
+
+  x = gen_reg_rtx (mode);
+  emit_insn (gen_spu_convert (x, r));
+  return x;
+}
diff --git a/gcc/config/spu/spu-elf.h b/gcc/config/spu/spu-elf.h
new file mode 100644 (file)
index 0000000..f20a701
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#ifndef OBJECT_FORMAT_ELF
+ #error elf.h included before elfos.h
+#endif
+
+#define BSS_SECTION_ASM_OP "\t.section .bss"
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+            asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+
+#undef  STARTFILE_SPEC
+#define STARTFILE_SPEC "crt1%O%s"
+
+#undef  ENDFILE_SPEC
+#define ENDFILE_SPEC   "crtend1%O%s"
+
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+
+#define DWARF2_DEBUGGING_INFO 1
+#define DWARF2_ASM_LINE_DEBUG_INFO 1
+
+#define SET_ASM_OP             "\t.set\t"
+
+#undef TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION  default_elf_asm_named_section
+
+#define EH_FRAME_IN_DATA_SECTION 1
+
+#define LINK_SPEC "%{mlarge-mem: --defsym __stack=0xfffffff0 }"
+
+#define LIB_SPEC \
+       "-( %{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}} -lgloss -)"
+
+/* Turn off warnings in the assembler too. */
+#undef ASM_SPEC
+#define ASM_SPEC  "%{w:-W}"
+
diff --git a/gcc/config/spu/spu-modes.def b/gcc/config/spu/spu-modes.def
new file mode 100644 (file)
index 0000000..a3397c5
--- /dev/null
@@ -0,0 +1,34 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Vector modes.  */
+VECTOR_MODES (INT, 2);        /*                 V2QI */ 
+VECTOR_MODES (INT, 4);        /*            V4QI V2HI */
+VECTOR_MODES (INT, 8);        /*       V8QI V4HI V2SI */
+VECTOR_MODES (INT, 16);       /* V16QI V8HI V4SI V2DI */
+        
+        
+VECTOR_MODES (FLOAT, 8);      /*            V4HF V2SF */ 
+VECTOR_MODES (FLOAT, 16);     /*       V8HF V4SF V2DF */ 
+        
+/* A special mode for the intr regsister so we can treat it differently
+   for conditional moves. */
+RANDOM_MODE (INTR);
+
+/* cse_insn needs an INT_MODE larger than WORD_MODE, otherwise some
+   parts of it will go into an infinite loop. */
+INT_MODE (OI, 32);
diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h
new file mode 100644 (file)
index 0000000..a42210d
--- /dev/null
@@ -0,0 +1,93 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#ifndef _SPU_PROTOS_
+#define _SPU_PROTOS_
+
+#include "rtl.h"
+
+extern enum machine_mode spu_eh_return_filter_mode (void);
+extern void spu_cpu_cpp_builtins (struct cpp_reader * pfile);
+extern void builtin_define_std (const char *);
+extern void spu_override_options (void);
+extern int valid_subreg (rtx op);
+extern void spu_expand_extv (rtx * ops, int unsignedp);
+extern void spu_expand_insv (rtx * ops);
+extern int spu_expand_block_move (rtx * ops);
+extern void spu_emit_branch_or_set (int is_set, enum rtx_code code,
+                                   rtx * operands);
+extern HOST_WIDE_INT const_double_to_hwint (rtx x);
+extern rtx hwint_to_const_double (enum machine_mode mode, HOST_WIDE_INT v);
+extern void print_operand_address (FILE * file, register rtx addr);
+extern void print_operand (FILE * file, rtx x, int code);
+extern int spu_saved_regs_size (void);
+extern int direct_return (void);
+extern void spu_expand_prologue (void);
+extern void spu_expand_epilogue (unsigned char sibcall_p);
+extern rtx spu_return_addr (int count, rtx frame);
+extern rtx spu_const (enum machine_mode mode, HOST_WIDE_INT val);
+extern struct rtx_def *spu_float_const (const char *string,
+                                       enum machine_mode mode);
+extern int immediate_load_p (rtx op, enum machine_mode mode);
+extern int logical_immediate_p (rtx op, enum machine_mode mode);
+extern int iohl_immediate_p (rtx op, enum machine_mode mode);
+extern int arith_immediate_p (rtx op, enum machine_mode mode,
+                             HOST_WIDE_INT low, HOST_WIDE_INT high);
+extern int legitimate_const (rtx x, int aligned);
+extern int spu_constant_address_p (rtx x);
+extern int spu_legitimate_constant_p (rtx x);
+extern int spu_legitimate_address (enum machine_mode mode, rtx x,
+                                  int reg_ok_strict);
+extern rtx spu_legitimize_address (rtx x, rtx oldx, enum machine_mode mode);
+extern int spu_initial_elimination_offset (int from, int to);
+extern rtx spu_function_value (tree type, tree func);
+extern rtx spu_function_arg (int cum, enum machine_mode mode, tree type,
+                            int named);
+extern void spu_va_start (tree valist, rtx nextarg);
+extern void spu_setup_incoming_varargs (int *cum, enum machine_mode mode,
+                                       tree type, int *pretend_size,
+                                       int no_rtl);
+extern void spu_conditional_register_usage (void);
+extern int aligned_mem_p (rtx mem);
+extern int spu_expand_mov (rtx * ops, enum machine_mode mode);
+extern void spu_split_load (rtx * ops);
+extern void spu_split_store (rtx * ops);
+extern int spu_valid_move (rtx * ops);
+extern int fsmbi_const_p (rtx x);
+extern void constant_to_array (enum machine_mode mode, rtx x,
+                              unsigned char *arr);
+extern rtx array_to_constant (enum machine_mode mode, unsigned char *arr);
+extern enum machine_mode spu_eh_return_filter_mode (void);
+extern void spu_allocate_stack (rtx op0, rtx op1);
+extern void spu_restore_stack_nonlocal (rtx op0, rtx op1);
+extern rtx spu_gen_subreg (enum machine_mode mode, rtx x);
+extern int spu_safe_dma(HOST_WIDE_INT channel);
+extern void spu_builtin_splats (rtx ops[]);
+extern void spu_builtin_extract (rtx ops[]);
+extern void spu_builtin_insert (rtx ops[]);
+extern void spu_builtin_promote (rtx ops[]);
+extern void spu_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt);
+extern void spu_expand_sign_extend (rtx ops[]);
+extern void spu_expand_vector_init (rtx target, rtx vals);
+
+/* spu-c.c */
+extern tree spu_resolve_overloaded_builtin (tree fndecl, tree fnargs);
+extern rtx spu_expand_builtin (tree exp, rtx target, rtx subtarget,
+                              enum machine_mode mode, int ignore);
+extern rtx spu_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+
+#endif
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
new file mode 100644 (file)
index 0000000..99a0ac8
--- /dev/null
@@ -0,0 +1,4469 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "recog.h"
+#include "obstack.h"
+#include "tree.h"
+#include "expr.h"
+#include "optabs.h"
+#include "except.h"
+#include "function.h"
+#include "output.h"
+#include "basic-block.h"
+#include "integrate.h"
+#include "toplev.h"
+#include "ggc.h"
+#include "hashtab.h"
+#include "tm_p.h"
+#include "target.h"
+#include "target-def.h"
+#include "langhooks.h"
+#include "reload.h"
+#include "cfglayout.h"
+#include "sched-int.h"
+#include "params.h"
+#include "assert.h"
+#include "c-common.h"
+#include "machmode.h"
+#include "tree-gimple.h"
+#include "tm-constrs.h"
+#include "spu-builtins.h"
+\f
+/*  Target specific attribute specifications.  */
+char regs_ever_allocated[FIRST_PSEUDO_REGISTER];
+
+/*  Prototypes and external defs.  */
+static void spu_init_builtins (void);
+static unsigned char spu_scalar_mode_supported_p (enum machine_mode mode);
+static unsigned char spu_vector_mode_supported_p (enum machine_mode mode);
+static rtx adjust_operand (rtx op, HOST_WIDE_INT * start);
+static rtx get_pic_reg (void);
+static int need_to_save_reg (int regno, int saving);
+static rtx frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset);
+static rtx frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset);
+static rtx frame_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm,
+                              rtx scratch);
+static void emit_nop_for_insn (rtx insn);
+static bool insn_clobbers_hbr (rtx insn);
+static void spu_emit_branch_hint (rtx before, rtx branch, rtx target,
+                                 int distance);
+static rtx get_branch_target (rtx branch);
+static void insert_branch_hints (void);
+static void insert_nops (void);
+static void spu_machine_dependent_reorg (void);
+static int spu_sched_issue_rate (void);
+static int spu_sched_variable_issue (FILE * dump, int verbose, rtx insn,
+                                    int can_issue_more);
+static int get_pipe (rtx insn);
+static int spu_sched_adjust_priority (rtx insn, int pri);
+static int spu_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost);
+static tree spu_handle_fndecl_attribute (tree * node, tree name, tree args,
+                                        int flags,
+                                        unsigned char *no_add_attrs);
+static tree spu_handle_vector_attribute (tree * node, tree name, tree args,
+                                        int flags,
+                                        unsigned char *no_add_attrs);
+static int spu_naked_function_p (tree func);
+static unsigned char spu_pass_by_reference (int *cum, enum machine_mode mode,
+                                           tree type, unsigned char named);
+static tree spu_build_builtin_va_list (void);
+static tree spu_gimplify_va_arg_expr (tree valist, tree type, tree * pre_p,
+                                     tree * post_p);
+static int regno_aligned_for_load (int regno);
+static int store_with_one_insn_p (rtx mem);
+static int reg_align (rtx reg);
+static int mem_is_padded_component_ref (rtx x);
+static bool spu_assemble_integer (rtx x, unsigned int size, int aligned_p);
+static void spu_asm_globalize_label (FILE * file, const char *name);
+static unsigned char spu_rtx_costs (rtx x, int code, int outer_code,
+                                   int *total);
+static unsigned char spu_function_ok_for_sibcall (tree decl, tree exp);
+static void spu_init_libfuncs (void);
+static bool spu_return_in_memory (tree type, tree fntype);
+
+extern const char *reg_names[];
+rtx spu_compare_op0, spu_compare_op1;
+
+enum spu_immediate {
+  SPU_NONE,
+  SPU_IL,
+  SPU_ILA,
+  SPU_ILH,
+  SPU_ILHU,
+  SPU_ORI,
+  SPU_ORHI,
+  SPU_ORBI,
+  SPU_IOHL,
+};
+
+static enum spu_immediate which_immediate_load (HOST_WIDE_INT val);
+static enum spu_immediate which_logical_immediate (HOST_WIDE_INT val);
+
+/* Built in types.  */
+tree spu_builtin_types[SPU_BTI_MAX];
+\f
+/*  TARGET overrides.  */
+
+#undef TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS spu_init_builtins
+
+#undef TARGET_RESOLVE_OVERLOADED_BUILTIN
+#define TARGET_RESOLVE_OVERLOADED_BUILTIN  spu_resolve_overloaded_builtin
+
+#undef TARGET_EXPAND_BUILTIN
+#define TARGET_EXPAND_BUILTIN spu_expand_builtin
+
+#undef TARGET_EH_RETURN_FILTER_MODE
+#define TARGET_EH_RETURN_FILTER_MODE spu_eh_return_filter_mode
+
+/* The .8byte directive doesn't seem to work well for a 32 bit
+   architecture. */
+#undef TARGET_ASM_UNALIGNED_DI_OP
+#define TARGET_ASM_UNALIGNED_DI_OP NULL
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS spu_rtx_costs
+
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE spu_sched_issue_rate
+
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE spu_sched_variable_issue
+
+#undef TARGET_SCHED_ADJUST_PRIORITY
+#define TARGET_SCHED_ADJUST_PRIORITY spu_sched_adjust_priority
+
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost
+
+const struct attribute_spec spu_attribute_table[];
+#undef  TARGET_ATTRIBUTE_TABLE
+#define TARGET_ATTRIBUTE_TABLE spu_attribute_table
+
+#undef TARGET_ASM_INTEGER
+#define TARGET_ASM_INTEGER spu_assemble_integer
+
+#undef TARGET_SCALAR_MODE_SUPPORTED_P
+#define TARGET_SCALAR_MODE_SUPPORTED_P spu_scalar_mode_supported_p
+
+#undef TARGET_VECTOR_MODE_SUPPORTED_P
+#define TARGET_VECTOR_MODE_SUPPORTED_P spu_vector_mode_supported_p
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL spu_function_ok_for_sibcall
+
+#undef TARGET_ASM_GLOBALIZE_LABEL
+#define TARGET_ASM_GLOBALIZE_LABEL spu_asm_globalize_label
+
+#undef TARGET_PASS_BY_REFERENCE
+#define TARGET_PASS_BY_REFERENCE spu_pass_by_reference
+
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
+
+#undef TARGET_BUILD_BUILTIN_VA_LIST
+#define TARGET_BUILD_BUILTIN_VA_LIST spu_build_builtin_va_list
+
+#undef TARGET_SETUP_INCOMING_VARARGS
+#define TARGET_SETUP_INCOMING_VARARGS spu_setup_incoming_varargs
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG spu_machine_dependent_reorg
+
+#undef TARGET_GIMPLIFY_VA_ARG_EXPR
+#define TARGET_GIMPLIFY_VA_ARG_EXPR spu_gimplify_va_arg_expr
+
+#undef TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT)
+
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS spu_init_libfuncs
+
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY spu_return_in_memory
+
+struct gcc_target targetm = TARGET_INITIALIZER;
+
+void
+spu_cpu_cpp_builtins (struct cpp_reader *pfile)
+{
+  extern void builtin_define_std (const char *);
+  builtin_define_std ("__SPU__");
+  cpp_assert (pfile, "cpu=spu");
+  cpp_assert (pfile, "machine=spu");
+  builtin_define_std ("__vector=__attribute__((__spu_vector__))");
+}
+
+/* Sometimes certain combinations of command options do not make sense
+   on a particular target machine.  You can define a macro
+   OVERRIDE_OPTIONS to take account of this. This macro, if defined, is
+   executed once just after all the command options have been parsed.  */
+void
+spu_override_options (void)
+{
+
+  /* Don't give warnings about the main() function. */
+  warn_main = 0;
+
+  /* Override some of the default param values.  With so many registers
+     larger values are better for these params.  */
+  if (MAX_UNROLLED_INSNS == 100)
+    MAX_UNROLLED_INSNS = 250;
+  if (MAX_PENDING_LIST_LENGTH == 32)
+    MAX_PENDING_LIST_LENGTH = 128;
+
+  flag_omit_frame_pointer = 1;
+
+  if (align_functions < 8)
+    align_functions = 8;
+}
+\f
+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
+   struct attribute_spec.handler.  */
+
+/*  Table of machine attributes.  */
+const struct attribute_spec spu_attribute_table[] =
+{
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+  { "naked",          0, 0, true,  false, false, spu_handle_fndecl_attribute },
+  { "spu_vector",     0, 0, false, true,  false, spu_handle_vector_attribute },
+  { NULL,             0, 0, false, false, false, NULL }
+};
+
+/* True if MODE is valid for the target.  By "valid", we mean able to
+   be manipulated in non-trivial ways.  In particular, this means all
+   the arithmetic is supported.  */
+static bool
+spu_scalar_mode_supported_p (enum machine_mode mode)
+{
+  switch (mode)
+    {
+    case QImode:
+    case HImode:
+    case SImode:
+    case SFmode:
+    case DImode:
+    case TImode:
+    case DFmode:
+      return true;
+
+    default:
+      return false;
+    }
+}
+
+/* Similarly for vector modes.  "Supported" here is less strict.  At
+   least some operations are supported; need to check optabs or builtins
+   for further details.  */
+static bool
+spu_vector_mode_supported_p (enum machine_mode mode)
+{
+  switch (mode)
+    {
+    case V16QImode:
+    case V8HImode:
+    case V4SImode:
+    case V2DImode:
+    case V4SFmode:
+    case V2DFmode:
+      return true;
+
+    default:
+      return false;
+    }
+}
+
+/* GCC assumes that in a paradoxical SUBREG the inner mode occupies the
+   least significant bytes of the outer mode.  This function returns
+   TRUE for the SUBREG's where this is correct.  */
+int
+valid_subreg (rtx op)
+{
+  enum machine_mode om = GET_MODE (op);
+  enum machine_mode im = GET_MODE (SUBREG_REG (op));
+  return om != VOIDmode && im != VOIDmode
+    && (GET_MODE_SIZE (im) == GET_MODE_SIZE (om)
+       || (GET_MODE_SIZE (im) <= 4 && GET_MODE_SIZE (om) <= 4));
+}
+
+/* When insv and ext[sz]v ar passed a TI SUBREG, we want to strip it off
+   and ajust the start offset. */
+static rtx
+adjust_operand (rtx op, HOST_WIDE_INT * start)
+{
+  enum machine_mode mode;
+  int op_size;
+  /* Strip any SUBREG */
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (start)
+       *start -=
+         GET_MODE_BITSIZE (GET_MODE (op)) -
+         GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op)));
+      op = SUBREG_REG (op);
+    }
+  /* If it is smaller than SI, assure a SUBREG */
+  op_size = GET_MODE_BITSIZE (GET_MODE (op));
+  if (op_size < 32)
+    {
+      if (start)
+       *start += 32 - op_size;
+      op_size = 32;
+    }
+  /* If it is not a MODE_INT (and/or it is smaller than SI) add a SUBREG. */
+  mode = mode_for_size (op_size, MODE_INT, 0);
+  if (mode != GET_MODE (op))
+    op = gen_rtx_SUBREG (mode, op, 0);
+  return op;
+}
+
+void
+spu_expand_extv (rtx ops[], int unsignedp)
+{
+  HOST_WIDE_INT width = INTVAL (ops[2]);
+  HOST_WIDE_INT start = INTVAL (ops[3]);
+  HOST_WIDE_INT src_size, dst_size;
+  enum machine_mode src_mode, dst_mode;
+  rtx dst = ops[0], src = ops[1];
+  rtx s;
+
+  dst = adjust_operand (ops[0], 0);
+  dst_mode = GET_MODE (dst);
+  dst_size = GET_MODE_BITSIZE (GET_MODE (dst));
+
+  if (GET_CODE (ops[1]) == MEM)
+    {
+      if (start + width > MEM_ALIGN (ops[1]))
+       {
+         rtx addr = gen_reg_rtx (SImode);
+         rtx shl = gen_reg_rtx (SImode);
+         rtx shr = gen_reg_rtx (SImode);
+         rtx w0 = gen_reg_rtx (TImode);
+         rtx w1 = gen_reg_rtx (TImode);
+         rtx a0, a1;
+         src = gen_reg_rtx (TImode);
+         emit_move_insn (addr, copy_rtx (XEXP (ops[1], 0)));
+         a0 = memory_address (TImode, addr);
+         a1 = memory_address (TImode, plus_constant (addr, 16));
+         emit_insn (gen_lq (w0, a0));
+         emit_insn (gen_lq (w1, a1));
+         emit_insn (gen_andsi3 (shl, addr, GEN_INT (15)));
+         emit_insn (gen_iorsi3 (shr, addr, GEN_INT (16)));
+         emit_insn (gen_shlqby_ti (w0, w0, shl));
+         emit_insn (gen_rotqmby_ti (w1, w1, shr));
+         emit_insn (gen_iorti3 (src, w0, w1));
+       }
+      else
+       {
+         rtx addr = gen_reg_rtx (SImode);
+         rtx a0;
+         emit_move_insn (addr, copy_rtx (XEXP (ops[1], 0)));
+         a0 = memory_address (TImode, addr);
+         src = gen_reg_rtx (TImode);
+         emit_insn (gen_lq (src, a0));
+         if (MEM_ALIGN (ops[1]) < 128)
+           {
+             rtx t = src;
+             src = gen_reg_rtx (TImode);
+             emit_insn (gen_rotqby_ti (src, t, addr));
+           }
+       }
+      /* Shifts in SImode are faster, use them if we can. */
+      if (start + width < 32)
+       {
+         rtx t = src;
+         src = gen_reg_rtx (SImode);
+         emit_insn (gen_spu_convert (src, t));
+       }
+    }
+
+  src = adjust_operand (src, &start);
+  src_mode = GET_MODE (src);
+  src_size = GET_MODE_BITSIZE (GET_MODE (src));
+
+  if (start > 0)
+    {
+      s = gen_reg_rtx (src_mode);
+      switch (src_mode)
+       {
+       case SImode:
+         emit_insn (gen_ashlsi3 (s, src, GEN_INT (start)));
+         break;
+       case DImode:
+         emit_insn (gen_ashldi3 (s, src, GEN_INT (start)));
+         break;
+       case TImode:
+         emit_insn (gen_ashlti3 (s, src, GEN_INT (start)));
+         break;
+       default:
+         abort ();
+       }
+      src = s;
+    }
+
+  if (width < src_size)
+    {
+      rtx pat;
+      int icode;
+      switch (src_mode)
+       {
+       case SImode:
+         icode = unsignedp ? CODE_FOR_lshrsi3 : CODE_FOR_ashrsi3;
+         break;
+       case DImode:
+         icode = unsignedp ? CODE_FOR_lshrdi3 : CODE_FOR_ashrdi3;
+         break;
+       case TImode:
+         icode = unsignedp ? CODE_FOR_lshrti3 : CODE_FOR_ashrti3;
+         break;
+       default:
+         abort ();
+       }
+      s = gen_reg_rtx (src_mode);
+      pat = GEN_FCN (icode) (s, src, GEN_INT (src_size - width));
+      emit_insn (pat);
+      src = s;
+    }
+
+  convert_move (dst, src, unsignedp);
+}
+
+void
+spu_expand_insv (rtx ops[])
+{
+  HOST_WIDE_INT width = INTVAL (ops[1]);
+  HOST_WIDE_INT start = INTVAL (ops[2]);
+  HOST_WIDE_INT maskbits;
+  enum machine_mode dst_mode, src_mode;
+  rtx dst = ops[0], src = ops[3];
+  int dst_size, src_size;
+  rtx mask;
+  rtx shift_reg;
+  int shift;
+
+
+  if (GET_CODE (ops[0]) == MEM)
+    dst = gen_reg_rtx (TImode);
+  else
+    dst = adjust_operand (dst, &start);
+  dst_mode = GET_MODE (dst);
+  dst_size = GET_MODE_BITSIZE (GET_MODE (dst));
+
+  if (CONSTANT_P (src))
+    {
+      enum machine_mode m =
+       (width <= 32 ? SImode : width <= 64 ? DImode : TImode);
+      src = force_reg (m, convert_to_mode (m, src, 0));
+    }
+  src = adjust_operand (src, 0);
+  src_mode = GET_MODE (src);
+  src_size = GET_MODE_BITSIZE (GET_MODE (src));
+
+  mask = gen_reg_rtx (dst_mode);
+  shift_reg = gen_reg_rtx (dst_mode);
+  shift = dst_size - start - width;
+
+  /* It's not safe to use subreg here because the compiler assumes
+     that the SUBREG_REG is right justified in the SUBREG. */
+  convert_move (shift_reg, src, 1);
+
+  if (shift > 0)
+    {
+      switch (dst_mode)
+       {
+       case SImode:
+         emit_insn (gen_ashlsi3 (shift_reg, shift_reg, GEN_INT (shift)));
+         break;
+       case DImode:
+         emit_insn (gen_ashldi3 (shift_reg, shift_reg, GEN_INT (shift)));
+         break;
+       case TImode:
+         emit_insn (gen_ashlti3 (shift_reg, shift_reg, GEN_INT (shift)));
+         break;
+       default:
+         abort ();
+       }
+    }
+  else if (shift < 0)
+    abort ();
+
+  switch (dst_size)
+    {
+    case 32:
+      maskbits = (-1ll << (32 - width - start));
+      if (start)
+       maskbits += (1ll << (32 - start));
+      emit_move_insn (mask, GEN_INT (maskbits));
+      break;
+    case 64:
+      maskbits = (-1ll << (64 - width - start));
+      if (start)
+       maskbits += (1ll << (64 - start));
+      emit_move_insn (mask, GEN_INT (maskbits));
+      break;
+    case 128:
+      {
+       unsigned char arr[16];
+       int i = start / 8;
+       memset (arr, 0, sizeof (arr));
+       arr[i] = 0xff >> (start & 7);
+       for (i++; i <= (start + width - 1) / 8; i++)
+         arr[i] = 0xff;
+       arr[i - 1] &= 0xff << (7 - ((start + width - 1) & 7));
+       emit_move_insn (mask, array_to_constant (TImode, arr));
+      }
+      break;
+    default:
+      abort ();
+    }
+  if (GET_CODE (ops[0]) == MEM)
+    {
+      rtx aligned = gen_reg_rtx (SImode);
+      rtx low = gen_reg_rtx (SImode);
+      rtx addr = gen_reg_rtx (SImode);
+      rtx rotl = gen_reg_rtx (SImode);
+      rtx mask0 = gen_reg_rtx (TImode);
+      rtx mem;
+
+      emit_move_insn (addr, XEXP (ops[0], 0));
+      emit_insn (gen_andsi3 (aligned, addr, GEN_INT (-16)));
+      emit_insn (gen_andsi3 (low, addr, GEN_INT (15)));
+      emit_insn (gen_negsi2 (rotl, low));
+      emit_insn (gen_rotqby_ti (shift_reg, shift_reg, rotl));
+      emit_insn (gen_rotqmby_ti (mask0, mask, rotl));
+      mem = change_address (ops[0], TImode, aligned);
+      set_mem_alias_set (mem, 0);
+      emit_move_insn (dst, mem);
+      emit_insn (gen_selb (dst, dst, shift_reg, mask0));
+      emit_move_insn (mem, dst);
+      if (start + width > MEM_ALIGN (ops[0]))
+       {
+         rtx shl = gen_reg_rtx (SImode);
+         rtx mask1 = gen_reg_rtx (TImode);
+         rtx dst1 = gen_reg_rtx (TImode);
+         rtx mem1;
+         emit_insn (gen_subsi3 (shl, GEN_INT (16), low));
+         emit_insn (gen_shlqby_ti (mask1, mask, shl));
+         mem1 = adjust_address (mem, TImode, 16);
+         set_mem_alias_set (mem1, 0);
+         emit_move_insn (dst1, mem1);
+         emit_insn (gen_selb (dst1, dst1, shift_reg, mask1));
+         emit_move_insn (mem1, dst1);
+       }
+    }
+  else
+    emit_insn (gen_selb (dst, dst, shift_reg, mask));
+}
+
+
+int
+spu_expand_block_move (rtx ops[])
+{
+  HOST_WIDE_INT bytes, align, offset;
+  rtx src, dst, sreg, dreg, target;
+  int i;
+  if (GET_CODE (ops[2]) != CONST_INT
+      || GET_CODE (ops[3]) != CONST_INT
+      || INTVAL (ops[2]) > (HOST_WIDE_INT) (MOVE_RATIO * 8))
+    return 0;
+
+  bytes = INTVAL (ops[2]);
+  align = INTVAL (ops[3]);
+
+  if (bytes <= 0)
+    return 1;
+
+  dst = ops[0];
+  src = ops[1];
+
+  if (align == 16)
+    {
+      for (offset = 0; offset + 16 <= bytes; offset += 16)
+       {
+         dst = adjust_address (ops[0], V16QImode, offset);
+         src = adjust_address (ops[1], V16QImode, offset);
+         emit_move_insn (dst, src);
+       }
+      if (offset < bytes)
+       {
+         rtx mask;
+         unsigned char arr[16] = { 0 };
+         for (i = 0; i < bytes - offset; i++)
+           arr[i] = 0xff;
+         dst = adjust_address (ops[0], V16QImode, offset);
+         src = adjust_address (ops[1], V16QImode, offset);
+         mask = gen_reg_rtx (V16QImode);
+         sreg = gen_reg_rtx (V16QImode);
+         dreg = gen_reg_rtx (V16QImode);
+         target = gen_reg_rtx (V16QImode);
+         emit_move_insn (mask, array_to_constant (V16QImode, arr));
+         emit_move_insn (dreg, dst);
+         emit_move_insn (sreg, src);
+         emit_insn (gen_selb (target, dreg, sreg, mask));
+         emit_move_insn (dst, target);
+       }
+      return 1;
+    }
+  return 0;
+}
+
+enum spu_comp_code
+{ SPU_EQ, SPU_GT, SPU_GTU };
+
+
+int spu_comp_icode[8][3] = {
+  {CODE_FOR_ceq_qi, CODE_FOR_cgt_qi, CODE_FOR_clgt_qi},
+  {CODE_FOR_ceq_hi, CODE_FOR_cgt_hi, CODE_FOR_clgt_hi},
+  {CODE_FOR_ceq_si, CODE_FOR_cgt_si, CODE_FOR_clgt_si},
+  {CODE_FOR_ceq_di, CODE_FOR_cgt_di, CODE_FOR_clgt_di},
+  {CODE_FOR_ceq_ti, CODE_FOR_cgt_ti, CODE_FOR_clgt_ti},
+  {CODE_FOR_ceq_sf, CODE_FOR_cgt_sf, 0},
+  {0, 0, 0},
+  {CODE_FOR_ceq_vec, 0, 0},
+};
+
+/* Generate a compare for CODE.  Return a brand-new rtx that represents
+   the result of the compare.   GCC can figure this out too if we don't
+   provide all variations of compares, but GCC always wants to use
+   WORD_MODE, we can generate better code in most cases if we do it
+   ourselves.  */
+void
+spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
+{
+  int reverse_compare = 0;
+  int reverse_test = 0;
+  rtx compare_result;
+  rtx comp_rtx;
+  rtx target = operands[0];
+  enum machine_mode comp_mode;
+  enum machine_mode op_mode;
+  enum spu_comp_code scode;
+  int index;
+
+  /* When spu_compare_op1 is a CONST_INT change (X >= C) to (X > C-1),
+     and so on, to keep the constant in operand 1. */
+  if (GET_CODE (spu_compare_op1) == CONST_INT)
+    {
+      HOST_WIDE_INT val = INTVAL (spu_compare_op1) - 1;
+      if (trunc_int_for_mode (val, GET_MODE (spu_compare_op0)) == val)
+       switch (code)
+         {
+         case GE:
+           spu_compare_op1 = GEN_INT (val);
+           code = GT;
+           break;
+         case LT:
+           spu_compare_op1 = GEN_INT (val);
+           code = LE;
+           break;
+         case GEU:
+           spu_compare_op1 = GEN_INT (val);
+           code = GTU;
+           break;
+         case LTU:
+           spu_compare_op1 = GEN_INT (val);
+           code = LEU;
+           break;
+         default:
+           break;
+         }
+    }
+
+  switch (code)
+    {
+    case GE:
+      reverse_compare = 1;
+      reverse_test = 1;
+      scode = SPU_GT;
+      break;
+    case LE:
+      reverse_compare = 0;
+      reverse_test = 1;
+      scode = SPU_GT;
+      break;
+    case LT:
+      reverse_compare = 1;
+      reverse_test = 0;
+      scode = SPU_GT;
+      break;
+    case GEU:
+      reverse_compare = 1;
+      reverse_test = 1;
+      scode = SPU_GTU;
+      break;
+    case LEU:
+      reverse_compare = 0;
+      reverse_test = 1;
+      scode = SPU_GTU;
+      break;
+    case LTU:
+      reverse_compare = 1;
+      reverse_test = 0;
+      scode = SPU_GTU;
+      break;
+    case NE:
+      reverse_compare = 0;
+      reverse_test = 1;
+      scode = SPU_EQ;
+      break;
+
+    case EQ:
+      scode = SPU_EQ;
+      break;
+    case GT:
+      scode = SPU_GT;
+      break;
+    case GTU:
+      scode = SPU_GTU;
+      break;
+    default:
+      scode = SPU_EQ;
+      break;
+    }
+
+  comp_mode = SImode;
+  op_mode = GET_MODE (spu_compare_op0);
+
+  switch (op_mode)
+    {
+    case QImode:
+      index = 0;
+      comp_mode = QImode;
+      break;
+    case HImode:
+      index = 1;
+      comp_mode = HImode;
+      break;
+    case SImode:
+      index = 2;
+      break;
+    case DImode:
+      index = 3;
+      break;
+    case TImode:
+      index = 4;
+      break;
+    case SFmode:
+      index = 5;
+      break;
+    case DFmode:
+      index = 6;
+      break;
+    case V16QImode:
+    case V8HImode:
+    case V4SImode:
+    case V2DImode:
+    case V4SFmode:
+    case V2DFmode:
+      index = 7;
+      break;
+    default:
+      abort ();
+    }
+
+  if (GET_MODE (spu_compare_op1) == DFmode)
+    {
+      rtx reg = gen_reg_rtx (DFmode);
+      if (!flag_unsafe_math_optimizations
+         || (scode != SPU_GT && scode != SPU_EQ))
+       abort ();
+      if (reverse_compare)
+       emit_insn (gen_subdf3 (reg, spu_compare_op1, spu_compare_op0));
+      else
+       emit_insn (gen_subdf3 (reg, spu_compare_op0, spu_compare_op1));
+      reverse_compare = 0;
+      spu_compare_op0 = reg;
+      spu_compare_op1 = CONST0_RTX (DFmode);
+    }
+
+  if (is_set == 0 && spu_compare_op1 == const0_rtx
+      && (GET_MODE (spu_compare_op0) == SImode
+         || GET_MODE (spu_compare_op0) == HImode) && scode == SPU_EQ)
+    {
+      /* Don't need to set a register with the result when we are 
+         comparing against zero and branching. */
+      reverse_test = !reverse_test;
+      compare_result = spu_compare_op0;
+    }
+  else
+    {
+      compare_result = gen_reg_rtx (comp_mode);
+
+      if (reverse_compare)
+       {
+         rtx t = spu_compare_op1;
+         spu_compare_op1 = spu_compare_op0;
+         spu_compare_op0 = t;
+       }
+
+      if (spu_comp_icode[index][scode] == 0)
+       abort ();
+
+      if (!(*insn_data[spu_comp_icode[index][scode]].operand[1].predicate)
+         (spu_compare_op0, op_mode))
+       spu_compare_op0 = force_reg (op_mode, spu_compare_op0);
+      if (!(*insn_data[spu_comp_icode[index][scode]].operand[2].predicate)
+         (spu_compare_op1, op_mode))
+       spu_compare_op1 = force_reg (op_mode, spu_compare_op1);
+      comp_rtx = GEN_FCN (spu_comp_icode[index][scode]) (compare_result,
+                                                        spu_compare_op0,
+                                                        spu_compare_op1);
+      if (comp_rtx == 0)
+       abort ();
+      emit_insn (comp_rtx);
+
+    }
+
+  if (is_set == 0)
+    {
+      rtx bcomp;
+      rtx loc_ref;
+
+      /* We don't have branch on QI compare insns, so we convert the
+         QI compare result to a HI result. */
+      if (comp_mode == QImode)
+       {
+         rtx old_res = compare_result;
+         compare_result = gen_reg_rtx (HImode);
+         comp_mode = HImode;
+         emit_insn (gen_extendqihi2 (compare_result, old_res));
+       }
+
+      if (reverse_test)
+       bcomp = gen_rtx_EQ (comp_mode, compare_result, const0_rtx);
+      else
+       bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx);
+
+      loc_ref = gen_rtx_LABEL_REF (VOIDmode, target);
+      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
+                                  gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
+                                                        loc_ref, pc_rtx)));
+    }
+  else if (is_set == 2)
+    {
+      int compare_size = GET_MODE_BITSIZE (comp_mode);
+      int target_size = GET_MODE_BITSIZE (GET_MODE (target));
+      enum machine_mode mode = mode_for_size (target_size, MODE_INT, 0);
+      rtx select_mask;
+      rtx op_t = operands[2];
+      rtx op_f = operands[3];
+
+      /* The result of the comparison can be SI, HI or QI mode.  Create a
+         mask based on that result. */
+      if (target_size > compare_size)
+       {
+         select_mask = gen_reg_rtx (mode);
+         emit_insn (gen_extend_compare (select_mask, compare_result));
+       }
+      else if (target_size < compare_size)
+       select_mask =
+         gen_rtx_SUBREG (mode, compare_result,
+                         (compare_size - target_size) / BITS_PER_UNIT);
+      else if (comp_mode != mode)
+       select_mask = gen_rtx_SUBREG (mode, compare_result, 0);
+      else
+       select_mask = compare_result;
+
+      if (GET_MODE (target) != GET_MODE (op_t)
+         || GET_MODE (target) != GET_MODE (op_f))
+       abort ();
+
+      if (reverse_test)
+       emit_insn (gen_selb (target, op_t, op_f, select_mask));
+      else
+       emit_insn (gen_selb (target, op_f, op_t, select_mask));
+    }
+  else
+    {
+      if (reverse_test)
+       emit_insn (gen_rtx_SET (VOIDmode, compare_result,
+                               gen_rtx_NOT (comp_mode, compare_result)));
+      if (GET_MODE (target) == SImode && GET_MODE (compare_result) == HImode)
+       emit_insn (gen_extendhisi2 (target, compare_result));
+      else if (GET_MODE (target) == SImode
+              && GET_MODE (compare_result) == QImode)
+       emit_insn (gen_extend_compare (target, compare_result));
+      else
+       emit_move_insn (target, compare_result);
+    }
+}
+
+HOST_WIDE_INT
+const_double_to_hwint (rtx x)
+{
+  HOST_WIDE_INT val;
+  REAL_VALUE_TYPE rv;
+  if (GET_MODE (x) == SFmode)
+    {
+      REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+      REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+    }
+  else if (GET_MODE (x) == DFmode)
+    {
+      long l[2];
+      REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+      REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
+      val = l[0];
+      val = (val << 32) | (l[1] & 0xffffffff);
+    }
+  else
+    abort ();
+  return val;
+}
+
+rtx
+hwint_to_const_double (enum machine_mode mode, HOST_WIDE_INT v)
+{
+  long tv[2];
+  REAL_VALUE_TYPE rv;
+  gcc_assert (mode == SFmode || mode == DFmode);
+
+  if (mode == SFmode)
+    tv[0] = (v << 32) >> 32;
+  else if (mode == DFmode)
+    {
+      tv[1] = (v << 32) >> 32;
+      tv[0] = v >> 32;
+    }
+  real_from_target (&rv, tv, mode);
+  return CONST_DOUBLE_FROM_REAL_VALUE (rv, mode);
+}
+
+void
+print_operand_address (FILE * file, register rtx addr)
+{
+  rtx reg;
+  rtx offset;
+
+  switch (GET_CODE (addr))
+    {
+    case REG:
+      fprintf (file, "0(%s)", reg_names[REGNO (addr)]);
+      break;
+
+    case PLUS:
+      reg = XEXP (addr, 0);
+      offset = XEXP (addr, 1);
+      if (GET_CODE (offset) == REG)
+       {
+         fprintf (file, "%s,%s", reg_names[REGNO (reg)],
+                  reg_names[REGNO (offset)]);
+       }
+      else if (GET_CODE (offset) == CONST_INT)
+       {
+         fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
+                  INTVAL (offset), reg_names[REGNO (reg)]);
+       }
+      else
+       abort ();
+      break;
+
+    case CONST:
+    case LABEL_REF:
+    case SYMBOL_REF:
+    case CONST_INT:
+      output_addr_const (file, addr);
+      break;
+
+    default:
+      debug_rtx (addr);
+      abort ();
+    }
+}
+
+void
+print_operand (FILE * file, rtx x, int code)
+{
+  enum machine_mode mode = GET_MODE (x);
+  HOST_WIDE_INT val;
+  unsigned char arr[16];
+  int xcode = GET_CODE (x);
+  if (GET_MODE (x) == VOIDmode)
+    switch (code)
+      {
+      case 'H':                        /* 128 bits, signed */
+      case 'L':                        /* 128 bits, signed */
+      case 'm':                        /* 128 bits, signed */
+      case 'T':                        /* 128 bits, signed */
+      case 't':                        /* 128 bits, signed */
+       mode = TImode;
+       break;
+      case 'G':                        /* 64 bits, signed */
+      case 'K':                        /* 64 bits, signed */
+      case 'k':                        /* 64 bits, signed */
+      case 'D':                        /* 64 bits, signed */
+      case 'd':                        /* 64 bits, signed */
+       mode = DImode;
+       break;
+      case 'F':                        /* 32 bits, signed */
+      case 'J':                        /* 32 bits, signed */
+      case 'j':                        /* 32 bits, signed */
+      case 's':                        /* 32 bits, signed */
+      case 'S':                        /* 32 bits, signed */
+       mode = SImode;
+       break;
+      }
+  switch (code)
+    {
+
+    case 'j':                  /* 32 bits, signed */
+    case 'k':                  /* 64 bits, signed */
+    case 'm':                  /* 128 bits, signed */
+      if (xcode == CONST_INT
+         || xcode == CONST_DOUBLE || xcode == CONST_VECTOR)
+       {
+         gcc_assert (logical_immediate_p (x, mode));
+         constant_to_array (mode, x, arr);
+         val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+         val = trunc_int_for_mode (val, SImode);
+         switch (which_logical_immediate (val))
+         {
+         case SPU_ORI:
+           break;
+         case SPU_ORHI:
+           fprintf (file, "h");
+           break;
+         case SPU_ORBI:
+           fprintf (file, "b");
+           break;
+         default:
+           gcc_unreachable();
+         }
+       }
+      else
+       gcc_unreachable();
+      return;
+
+    case 'J':                  /* 32 bits, signed */
+    case 'K':                  /* 64 bits, signed */
+    case 'L':                  /* 128 bits, signed */
+      if (xcode == CONST_INT
+         || xcode == CONST_DOUBLE || xcode == CONST_VECTOR)
+       {
+         gcc_assert (logical_immediate_p (x, mode)
+                     || iohl_immediate_p (x, mode));
+         constant_to_array (mode, x, arr);
+         val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+         val = trunc_int_for_mode (val, SImode);
+         switch (which_logical_immediate (val))
+         {
+         case SPU_ORI:
+         case SPU_IOHL:
+           break;
+         case SPU_ORHI:
+           val = trunc_int_for_mode (val, HImode);
+           break;
+         case SPU_ORBI:
+           val = trunc_int_for_mode (val, QImode);
+           break;
+         default:
+           gcc_unreachable();
+         }
+         fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
+       }
+      else
+       gcc_unreachable();
+      return;
+
+    case 't':                  /* 128 bits, signed */
+    case 'd':                  /* 64 bits, signed */
+    case 's':                  /* 32 bits, signed */
+      if (xcode == CONST_INT
+         || xcode == CONST_DOUBLE || xcode == CONST_VECTOR)
+       {
+         gcc_assert (immediate_load_p (x, mode));
+         constant_to_array (mode, x, arr);
+         val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+         val = trunc_int_for_mode (val, SImode);
+         switch (which_immediate_load (val))
+         {
+         case SPU_IL:
+           break;
+         case SPU_ILA:
+           fprintf (file, "a");
+           break;
+         case SPU_ILH:
+           fprintf (file, "h");
+           break;
+         case SPU_ILHU:
+           fprintf (file, "hu");
+           break;
+         default:
+           gcc_unreachable();
+         }
+       }
+      else if (xcode == SYMBOL_REF || xcode == LABEL_REF || xcode == CONST)
+       fprintf (file, "a");
+      else
+       gcc_unreachable ();
+      return;
+
+    case 'T':                  /* 128 bits, signed */
+    case 'D':                  /* 64 bits, signed */
+    case 'S':                  /* 32 bits, signed */
+      if (xcode == CONST_INT
+         || xcode == CONST_DOUBLE || xcode == CONST_VECTOR)
+       {
+         gcc_assert (immediate_load_p (x, mode));
+         constant_to_array (mode, x, arr);
+         val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+         val = trunc_int_for_mode (val, SImode);
+         switch (which_immediate_load (val))
+           {
+           case SPU_IL:
+           case SPU_ILA:
+             break;
+           case SPU_ILH:
+           case SPU_ILHU:
+             val = trunc_int_for_mode (((arr[0] << 8) | arr[1]), HImode);
+             break;
+           default:
+             gcc_unreachable();
+           }
+         fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
+       }
+      else if (xcode == CONST || xcode == SYMBOL_REF || xcode == LABEL_REF)
+       output_addr_const (file, x);
+      else
+       gcc_unreachable ();
+      return;
+
+    case 'F':
+    case 'G':
+    case 'H':
+      if (xcode == CONST_INT
+         || xcode == CONST_DOUBLE || xcode == CONST_VECTOR)
+       {                       /* immediate operand for fsmbi */
+         int i;
+         HOST_WIDE_INT val = 0;
+         unsigned char arr[16];
+         constant_to_array (mode, x, arr);
+         for (i = 0; i < 16; i++)
+           {
+             val <<= 1;
+             val |= arr[i] & 1;
+           }
+         print_operand (file, GEN_INT (val), 0);
+       }
+      else
+       gcc_unreachable();
+      return;
+
+    case 'C':
+      if (xcode == CONST_INT)
+       {
+         /* Only 4 least significant bits are relevant for generate
+            control word instructions. */
+         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 15);
+         return;
+       }
+      break;
+
+    case 'M':                  /* print code for c*d */
+      if (GET_CODE (x) == CONST_INT)
+       switch (INTVAL (x))
+         {
+         case 1:
+           fprintf (file, "b");
+           break;
+         case 2:
+           fprintf (file, "h");
+           break;
+         case 4:
+           fprintf (file, "w");
+           break;
+         case 8:
+           fprintf (file, "d");
+           break;
+         default:
+           gcc_unreachable();
+         }
+      else
+       gcc_unreachable();
+      return;
+
+    case 'N':                  /* Negate the operand */
+      if (xcode == CONST_INT)
+       fprintf (file, HOST_WIDE_INT_PRINT_DEC, -INTVAL (x));
+      else if (xcode == CONST_VECTOR)
+       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+                -INTVAL (CONST_VECTOR_ELT (x, 0)));
+      return;
+
+    case 'I':                  /* enable/disable interrupts */
+      if (xcode == CONST_INT)
+       fprintf (file, "%s",  INTVAL (x) == 0 ? "d" : "e");
+      return;
+
+    case 'b':                  /* branch modifiers */
+      if (xcode == REG)
+       fprintf (file, "%s", GET_MODE (x) == HImode ? "h" : "");
+      else if (COMPARISON_P (x))
+       fprintf (file, "%s", xcode == NE ? "n" : "");
+      return;
+
+    case 'i':                  /* indirect call */
+      if (xcode == MEM)
+       {
+         if (GET_CODE (XEXP (x, 0)) == REG)
+           /* Used in indirect function calls. */
+           fprintf (file, "%s", reg_names[REGNO (XEXP (x, 0))]);
+         else
+           output_address (XEXP (x, 0));
+       }
+      return;
+
+    case 'p':                  /* load/store */
+      if (xcode == MEM)
+       {
+         x = XEXP (x, 0);
+         xcode = GET_CODE (x);
+       }
+      if (xcode == REG)
+       fprintf (file, "d");
+      else if (xcode == CONST_INT)
+       fprintf (file, "a");
+      else if (xcode == CONST || xcode == SYMBOL_REF || xcode == LABEL_REF)
+       fprintf (file, "r");
+      else if (xcode == PLUS || xcode == LO_SUM)
+       {
+         if (GET_CODE (XEXP (x, 1)) == REG)
+           fprintf (file, "x");
+         else
+           fprintf (file, "d");
+       }
+      return;
+
+    case 0:
+      if (xcode == REG)
+       fprintf (file, "%s", reg_names[REGNO (x)]);
+      else if (xcode == MEM)
+       output_address (XEXP (x, 0));
+      else if (xcode == CONST_VECTOR)
+       output_addr_const (file, CONST_VECTOR_ELT (x, 0));
+      else
+       output_addr_const (file, x);
+      return;
+
+    default:
+      output_operand_lossage ("invalid %%xn code");
+    }
+  gcc_unreachable ();
+}
+
+extern char call_used_regs[];
+extern char regs_ever_live[];
+
+/* For PIC mode we've reserved PIC_OFFSET_TABLE_REGNUM, which is a
+   caller saved register.  For leaf functions it is more efficient to
+   use a volatile register because we won't need to save and restore the
+   pic register.  This routine is only valid after register allocation
+   is completed, so we can pick an unused register.  */
+static rtx
+get_pic_reg (void)
+{
+  rtx pic_reg = pic_offset_table_rtx;
+  if (!reload_completed && !reload_in_progress)
+    abort ();
+  return pic_reg;
+}
+
+/* SAVING is TRUE when we are generating the actual load and store
+   instructions for REGNO.  When determining the size of the stack
+   needed for saving register we must allocate enough space for the
+   worst case, because we don't always have the information early enough
+   to not allocate it.  But we can at least eliminate the actual loads
+   and stores during the prologue/epilogue.  */
+static int
+need_to_save_reg (int regno, int saving)
+{
+  if (regs_ever_live[regno] && !call_used_regs[regno])
+    return 1;
+  if (flag_pic
+      && regno == PIC_OFFSET_TABLE_REGNUM
+      && (!saving || current_function_uses_pic_offset_table)
+      && (!saving
+         || !current_function_is_leaf || regs_ever_live[LAST_ARG_REGNUM]))
+    return 1;
+  return 0;
+}
+
+/* This function is only correct starting with local register
+   allocation */
+int
+spu_saved_regs_size (void)
+{
+  int reg_save_size = 0;
+  int regno;
+
+  for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
+    if (need_to_save_reg (regno, 0))
+      reg_save_size += 0x10;
+  return reg_save_size;
+}
+
+static rtx
+frame_emit_store (int regno, rtx addr, HOST_WIDE_INT offset)
+{
+  rtx reg = gen_rtx_REG (V4SImode, regno);
+  rtx mem =
+    gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset)));
+  return emit_insn (gen_movv4si (mem, reg));
+}
+
+static rtx
+frame_emit_load (int regno, rtx addr, HOST_WIDE_INT offset)
+{
+  rtx reg = gen_rtx_REG (V4SImode, regno);
+  rtx mem =
+    gen_frame_mem (V4SImode, gen_rtx_PLUS (Pmode, addr, GEN_INT (offset)));
+  return emit_insn (gen_movv4si (reg, mem));
+}
+
+/* This happens after reload, so we need to expand it.  */
+static rtx
+frame_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT imm, rtx scratch)
+{
+  rtx insn;
+  if (satisfies_constraint_K (GEN_INT (imm)))
+    {
+      insn = emit_insn (gen_addsi3 (dst, src, GEN_INT (imm)));
+    }
+  else
+    {
+      insn = emit_insn (gen_movsi (scratch, gen_int_mode (imm, SImode)));
+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
+                                           REG_NOTES (insn));
+      insn = emit_insn (gen_addsi3 (dst, src, scratch));
+      if (REGNO (src) == REGNO (scratch))
+       abort ();
+    }
+  if (REGNO (dst) == REGNO (scratch))
+    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
+                                         REG_NOTES (insn));
+  return insn;
+}
+
+/* Return nonzero if this function is known to have a null epilogue.  */
+
+int
+direct_return (void)
+{
+  if (reload_completed)
+    {
+      if (cfun->static_chain_decl == 0
+         && (spu_saved_regs_size ()
+             + get_frame_size ()
+             + current_function_outgoing_args_size
+             + current_function_pretend_args_size == 0)
+         && current_function_is_leaf)
+       return 1;
+    }
+  return 0;
+}
+
+/*
+   The stack frame looks like this:
+         +-------------+
+         |  incoming   | 
+      AP |    args     | 
+         +-------------+
+         | $lr save    |
+         +-------------+
+ prev SP | back chain  | 
+         +-------------+
+         |  var args   | 
+         |  reg save   | current_function_pretend_args_size bytes
+         +-------------+
+         |    ...      | 
+         | saved regs  | spu_saved_regs_size() bytes
+         +-------------+
+         |    ...      | 
+      FP |   vars      | get_frame_size()  bytes
+         +-------------+
+         |    ...      | 
+         |  outgoing   | 
+         |    args     | current_function_outgoing_args_size bytes
+         +-------------+
+         | $lr of next |
+         |   frame     | 
+         +-------------+
+      SP | back chain  | 
+         +-------------+
+
+*/
+void
+spu_expand_prologue (void)
+{
+  HOST_WIDE_INT size = get_frame_size (), offset, regno;
+  HOST_WIDE_INT total_size;
+  HOST_WIDE_INT saved_regs_size;
+  rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+  rtx scratch_reg_0, scratch_reg_1;
+  rtx insn, real;
+
+  /* A NOTE_INSN_DELETED is supposed to be at the start and end of
+     the "toplevel" insn chain.  */
+  emit_note (NOTE_INSN_DELETED);
+
+  if (flag_pic && optimize == 0)
+    current_function_uses_pic_offset_table = 1;
+
+  if (spu_naked_function_p (current_function_decl))
+    return;
+
+  scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1);
+  scratch_reg_1 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 2);
+
+  saved_regs_size = spu_saved_regs_size ();
+  total_size = size + saved_regs_size
+    + current_function_outgoing_args_size
+    + current_function_pretend_args_size;
+
+  if (!current_function_is_leaf
+      || current_function_calls_alloca || total_size > 0)
+    total_size += STACK_POINTER_OFFSET;
+
+  /* Save this first because code after this might use the link
+     register as a scratch register. */
+  if (!current_function_is_leaf)
+    {
+      insn = frame_emit_store (LINK_REGISTER_REGNUM, sp_reg, 16);
+      RTX_FRAME_RELATED_P (insn) = 1;
+    }
+
+  if (total_size > 0)
+    {
+      offset = -current_function_pretend_args_size;
+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
+       if (need_to_save_reg (regno, 1))
+         {
+           offset -= 16;
+           insn = frame_emit_store (regno, sp_reg, offset);
+           RTX_FRAME_RELATED_P (insn) = 1;
+         }
+    }
+
+  if (flag_pic && current_function_uses_pic_offset_table)
+    {
+      rtx pic_reg = get_pic_reg ();
+      insn = emit_insn (gen_load_pic_offset (pic_reg, scratch_reg_0));
+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
+                                           REG_NOTES (insn));
+      insn = emit_insn (gen_subsi3 (pic_reg, pic_reg, scratch_reg_0));
+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
+                                           REG_NOTES (insn));
+    }
+
+  if (total_size > 0)
+    {
+      if (flag_stack_check)
+       {
+         /* We compare agains total_size-1 because
+            ($sp >= total_size) <=> ($sp > total_size-1) */
+         rtx scratch_v4si = gen_rtx_REG (V4SImode, REGNO (scratch_reg_0));
+         rtx sp_v4si = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM);
+         rtx size_v4si = spu_const (V4SImode, total_size - 1);
+         if (!satisfies_constraint_K (GEN_INT (total_size - 1)))
+           {
+             emit_move_insn (scratch_v4si, size_v4si);
+             size_v4si = scratch_v4si;
+           }
+         emit_insn (gen_cgt_v4si (scratch_v4si, sp_v4si, size_v4si));
+         emit_insn (gen_vec_extractv4si
+                    (scratch_reg_0, scratch_v4si, GEN_INT (1)));
+         emit_insn (gen_spu_heq (scratch_reg_0, GEN_INT (0)));
+       }
+
+      /* Adjust the stack pointer, and make sure scratch_reg_0 contains
+         the value of the previous $sp because we save it as the back
+         chain. */
+      if (total_size <= 2000)
+       {
+         /* In this case we save the back chain first. */
+         insn = frame_emit_store (STACK_POINTER_REGNUM, sp_reg, -total_size);
+         RTX_FRAME_RELATED_P (insn) = 1;
+         insn =
+           frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_0);
+       }
+      else if (satisfies_constraint_K (GEN_INT (-total_size)))
+       {
+         insn = emit_move_insn (scratch_reg_0, sp_reg);
+         RTX_FRAME_RELATED_P (insn) = 1;
+         insn =
+           emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size)));
+       }
+      else
+       {
+         insn = emit_move_insn (scratch_reg_0, sp_reg);
+         RTX_FRAME_RELATED_P (insn) = 1;
+         insn =
+           frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_1);
+       }
+      RTX_FRAME_RELATED_P (insn) = 1;
+      real = gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size));
+      REG_NOTES (insn) =
+       gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, real, REG_NOTES (insn));
+
+      if (total_size > 2000)
+       {
+         /* Save the back chain ptr */
+         insn = frame_emit_store (REGNO (scratch_reg_0), sp_reg, 0);
+         RTX_FRAME_RELATED_P (insn) = 1;
+       }
+
+      if (frame_pointer_needed)
+       {
+         rtx fp_reg = gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM);
+         HOST_WIDE_INT fp_offset = STACK_POINTER_OFFSET
+           + current_function_outgoing_args_size;
+         /* Set the new frame_pointer */
+         frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0);
+       }
+    }
+
+  emit_note (NOTE_INSN_DELETED);
+}
+
+void
+spu_expand_epilogue (bool sibcall_p)
+{
+  int size = get_frame_size (), offset, regno;
+  HOST_WIDE_INT saved_regs_size, total_size;
+  rtx sp_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
+  rtx jump, scratch_reg_0;
+
+  /* A NOTE_INSN_DELETED is supposed to be at the start and end of
+     the "toplevel" insn chain.  */
+  emit_note (NOTE_INSN_DELETED);
+
+  if (spu_naked_function_p (current_function_decl))
+    return;
+
+  scratch_reg_0 = gen_rtx_REG (SImode, LAST_ARG_REGNUM + 1);
+
+  saved_regs_size = spu_saved_regs_size ();
+  total_size = size + saved_regs_size
+    + current_function_outgoing_args_size
+    + current_function_pretend_args_size;
+
+  if (!current_function_is_leaf
+      || current_function_calls_alloca || total_size > 0)
+    total_size += STACK_POINTER_OFFSET;
+
+  if (total_size > 0)
+    {
+      if (current_function_calls_alloca)
+       /* Load it from the back chain because our save_stack_block and
+          restore_stack_block do nothing. */
+       frame_emit_load (STACK_POINTER_REGNUM, sp_reg, 0);
+      else
+       frame_emit_add_imm (sp_reg, sp_reg, total_size, scratch_reg_0);
+
+
+      if (saved_regs_size > 0)
+       {
+         offset = -current_function_pretend_args_size;
+         for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
+           if (need_to_save_reg (regno, 1))
+             {
+               offset -= 0x10;
+               frame_emit_load (regno, sp_reg, offset);
+             }
+       }
+    }
+
+  if (!current_function_is_leaf)
+    frame_emit_load (LINK_REGISTER_REGNUM, sp_reg, 16);
+
+  if (!sibcall_p)
+    {
+      emit_insn (gen_rtx_USE
+                (VOIDmode, gen_rtx_REG (SImode, LINK_REGISTER_REGNUM)));
+      jump = emit_jump_insn (gen__return ());
+      emit_barrier_after (jump);
+    }
+
+  emit_note (NOTE_INSN_DELETED);
+}
+
+rtx
+spu_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
+{
+  if (count != 0)
+    return 0;
+  /* This is inefficient because it ends up copying to a save-register
+     which then gets saved even though $lr has already been saved.  But
+     it does generate better code for leaf functions and we don't need
+     to use RETURN_ADDRESS_POINTER_REGNUM to get it working.  It's only
+     used for __builtin_return_address anyway, so maybe we don't care if
+     it's inefficient. */
+  return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
+}
+\f
+
+/* Given VAL, generate a constant appropriate for MODE.
+   If MODE is a vector mode, every element will be VAL.
+   For TImode, VAL will be zero extended to 128 bits. */
+rtx
+spu_const (enum machine_mode mode, HOST_WIDE_INT val)
+{
+  rtx inner;
+  rtvec v;
+  int units, i;
+
+  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
+             || GET_MODE_CLASS (mode) == MODE_FLOAT
+             || GET_MODE_CLASS (mode) == MODE_VECTOR_INT
+             || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT);
+
+  if (GET_MODE_CLASS (mode) == MODE_INT)
+    return immed_double_const (val, 0, mode);
+
+  /* val is the bit representation of the float */
+  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+    return hwint_to_const_double (mode, val);
+
+  if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+    inner = immed_double_const (val, 0, GET_MODE_INNER (mode));
+  else 
+    inner = hwint_to_const_double (GET_MODE_INNER (mode), val);
+
+  units = GET_MODE_NUNITS (mode);
+
+  v = rtvec_alloc (units);
+
+  for (i = 0; i < units; ++i)
+    RTVEC_ELT (v, i) = inner;
+
+  return gen_rtx_CONST_VECTOR (mode, v);
+}
+\f
+/* branch hint stuff */
+
+/* The hardware requires 8 insns between a hint and the branch it
+   effects.  This variable describes how many rtl instructions the
+   compiler needs to see before inserting a hint.  (FIXME: We should
+   accept less and insert nops to enforce it because hinting is always
+   profitable for performance, but we do need to be careful of code
+   size.) */
+int spu_hint_dist = (8 * 4);
+
+/* An array of these is used to propagate hints to predecessor blocks. */
+struct spu_bb_info
+{
+  rtx prop_jump;               /* propogated from another block */
+  basic_block bb;              /* the orignal block. */
+};
+
+/* The special $hbr register is used to prevent the insn scheduler from
+   moving hbr insns across instructions which invalidate them.  It
+   should only be used in a clobber, and this function searches for
+   insns which clobber it.  */
+static bool
+insn_clobbers_hbr (rtx insn)
+{
+  if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == PARALLEL)
+    {
+      rtx parallel = PATTERN (insn);
+      rtx clobber;
+      int j;
+      for (j = XVECLEN (parallel, 0) - 1; j >= 0; j--)
+       {
+         clobber = XVECEXP (parallel, 0, j);
+         if (GET_CODE (clobber) == CLOBBER
+             && GET_CODE (XEXP (clobber, 0)) == REG
+             && REGNO (XEXP (clobber, 0)) == HBR_REGNUM)
+           return 1;
+       }
+    }
+  return 0;
+}
+
+static void
+spu_emit_branch_hint (rtx before, rtx branch, rtx target, int distance)
+{
+  rtx branch_label;
+  rtx hint, insn, prev, next;
+
+  if (before == 0 || branch == 0 || target == 0)
+    return;
+
+  if (distance > 600)
+    return;
+
+
+  branch_label = gen_label_rtx ();
+  LABEL_NUSES (branch_label)++;
+  LABEL_PRESERVE_P (branch_label) = 1;
+  insn = emit_label_before (branch_label, branch);
+  branch_label = gen_rtx_LABEL_REF (VOIDmode, branch_label);
+
+  /* If the previous insn is pipe0, make the hbr dual issue with it.  If
+     the current insn is pipe0, dual issue with it. */
+  prev = prev_active_insn (before);
+  if (prev && get_pipe (prev) == 0)
+    hint = emit_insn_before (gen_hbr (branch_label, target), before);
+  else if (get_pipe (before) == 0 && distance > spu_hint_dist)
+    {
+      next = next_active_insn (before);
+      hint = emit_insn_after (gen_hbr (branch_label, target), before);
+      if (next)
+       PUT_MODE (next, TImode);
+    }
+  else
+    {
+      hint = emit_insn_before (gen_hbr (branch_label, target), before);
+      PUT_MODE (hint, TImode);
+    }
+  recog_memoized (hint);
+}
+
+/* Returns 0 if we don't want a hint for this branch.  Otherwise return
+   the rtx for the branch target. */
+static rtx
+get_branch_target (rtx branch)
+{
+  if (GET_CODE (branch) == JUMP_INSN)
+    {
+      rtx set, src;
+
+      /* Return statements */
+      if (GET_CODE (PATTERN (branch)) == RETURN)
+       return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM);
+
+      /* jump table */
+      if (GET_CODE (PATTERN (branch)) == ADDR_VEC
+         || GET_CODE (PATTERN (branch)) == ADDR_DIFF_VEC)
+       return 0;
+
+      set = single_set (branch);
+      src = SET_SRC (set);
+      if (GET_CODE (SET_DEST (set)) != PC)
+       abort ();
+
+      if (GET_CODE (src) == IF_THEN_ELSE)
+       {
+         rtx lab = 0;
+         rtx note = find_reg_note (branch, REG_BR_PROB, 0);
+         if (note)
+           {
+             /* If the more probable case is not a fall through, then
+                try a branch hint.  */
+             HOST_WIDE_INT prob = INTVAL (XEXP (note, 0));
+             if (prob > (REG_BR_PROB_BASE * 6 / 10)
+                 && GET_CODE (XEXP (src, 1)) != PC)
+               lab = XEXP (src, 1);
+             else if (prob < (REG_BR_PROB_BASE * 4 / 10)
+                      && GET_CODE (XEXP (src, 2)) != PC)
+               lab = XEXP (src, 2);
+           }
+         if (lab)
+           {
+             if (GET_CODE (lab) == RETURN)
+               return gen_rtx_REG (SImode, LINK_REGISTER_REGNUM);
+             return lab;
+           }
+         return 0;
+       }
+
+      return src;
+    }
+  else if (GET_CODE (branch) == CALL_INSN)
+    {
+      rtx call;
+      /* All of our call patterns are in a PARALLEL and the CALL is
+         the first pattern in the PARALLEL. */
+      if (GET_CODE (PATTERN (branch)) != PARALLEL)
+       abort ();
+      call = XVECEXP (PATTERN (branch), 0, 0);
+      if (GET_CODE (call) == SET)
+       call = SET_SRC (call);
+      if (GET_CODE (call) != CALL)
+       abort ();
+      return XEXP (XEXP (call, 0), 0);
+    }
+  return 0;
+}
+
+static void
+insert_branch_hints (void)
+{
+  struct spu_bb_info *spu_bb_info;
+  rtx branch, insn, next;
+  rtx branch_target = 0;
+  int branch_addr = 0, insn_addr, head_addr;
+  basic_block bb;
+  unsigned int j;
+
+  spu_bb_info =
+    (struct spu_bb_info *) xcalloc (last_basic_block + 1,
+                                   sizeof (struct spu_bb_info));
+
+  /* We need exact insn addresses and lengths.  */
+  shorten_branches (get_insns ());
+
+  FOR_EACH_BB_REVERSE (bb)
+  {
+    head_addr = INSN_ADDRESSES (INSN_UID (BB_HEAD (bb)));
+    branch = 0;
+    if (spu_bb_info[bb->index].prop_jump)
+      {
+       branch = spu_bb_info[bb->index].prop_jump;
+       branch_target = get_branch_target (branch);
+       branch_addr = INSN_ADDRESSES (INSN_UID (branch));
+      }
+    /* Search from end of a block to beginning.   In this loop, find
+       jumps which need a branch and emit them only when:
+       - it's an indirect branch and we're at the insn which sets
+       the register  
+       - we're at an insn that will invalidate the hint. e.g., a
+       call, another hint insn, inline asm that clobbers $hbr, and
+       some inlined operations (divmodsi4).  Don't consider jumps
+       because they are only at the end of a block and are
+       considered when we are deciding whether to propagate
+       - we're getting too far away from the branch.  The hbr insns
+       only have a signed 10 bit offset
+       We go back as far as possible so the branch will be considered
+       for propagation when we get to the beginning of the block.  */
+    next = 0;
+    for (insn = BB_END (bb); insn; insn = PREV_INSN (insn))
+      {
+       if (INSN_P (insn))
+         {
+           insn_addr = INSN_ADDRESSES (INSN_UID (insn));
+           if (branch && next
+               && ((GET_CODE (branch_target) == REG
+                    && set_of (branch_target, insn) != NULL_RTX)
+                   || insn_clobbers_hbr (insn)
+                   || branch_addr - insn_addr > 600))
+             {
+               int next_addr = INSN_ADDRESSES (INSN_UID (next));
+               if (insn != BB_END (bb)
+                   && branch_addr - next_addr >= spu_hint_dist)
+                 {
+                   if (dump_file)
+                     fprintf (dump_file,
+                              "hint for %i in block %i before %i\n",
+                              INSN_UID (branch), bb->index, INSN_UID (next));
+                   spu_emit_branch_hint (next, branch, branch_target,
+                                         branch_addr - next_addr);
+                 }
+               branch = 0;
+             }
+
+           /* JUMP_P will only be true at the end of a block.  When
+              branch is already set it means we've previously decided
+              to propagate a hint for that branch into this block. */
+           if (CALL_P (insn) || (JUMP_P (insn) && !branch))
+             {
+               branch = 0;
+               if ((branch_target = get_branch_target (insn)))
+                 {
+                   branch = insn;
+                   branch_addr = insn_addr;
+                 }
+             }
+
+           /* When a branch hint is emitted it will be inserted
+              before "next".  Make sure next is the beginning of a
+              cycle to minimize impact on the scheduled insns. */
+           if (GET_MODE (insn) == TImode)
+             next = insn;
+         }
+       if (insn == BB_HEAD (bb))
+         break;
+      }
+
+    if (branch)
+      {
+       /* If we haven't emitted a hint for this branch yet, it might
+          be profitable to emit it in one of the predecessor blocks,
+          especially for loops.  */
+       rtx bbend;
+       basic_block prev = 0, prop = 0, prev2 = 0;
+       int loop_exit = 0, simple_loop = 0;
+       int next_addr = 0;
+       if (next)
+         next_addr = INSN_ADDRESSES (INSN_UID (next));
+
+       for (j = 0; j < EDGE_COUNT (bb->preds); j++)
+         if (EDGE_PRED (bb, j)->flags & EDGE_FALLTHRU)
+           prev = EDGE_PRED (bb, j)->src;
+         else
+           prev2 = EDGE_PRED (bb, j)->src;
+
+       for (j = 0; j < EDGE_COUNT (bb->succs); j++)
+         if (EDGE_SUCC (bb, j)->flags & EDGE_LOOP_EXIT)
+           loop_exit = 1;
+         else if (EDGE_SUCC (bb, j)->dest == bb)
+           simple_loop = 1;
+
+       /* If this branch is a loop exit then propagate to previous
+          fallthru block. This catches the cases when it is a simple
+          loop or when there is an initial branch into the loop. */
+       if (prev && loop_exit && prev->loop_depth <= bb->loop_depth)
+         prop = prev;
+
+       /* If there is only one adjacent predecessor.  Don't propagate
+          outside this loop.  This loop_depth test isn't perfect, but
+          I'm not sure the loop_father member is valid at this point.  */
+       else if (prev && single_pred_p (bb)
+                && prev->loop_depth == bb->loop_depth)
+         prop = prev;
+
+       /* If this is the JOIN block of a simple IF-THEN then
+          propogate the hint to the HEADER block. */
+       else if (prev && prev2
+                && EDGE_COUNT (bb->preds) == 2
+                && EDGE_COUNT (prev->preds) == 1
+                && EDGE_PRED (prev, 0)->src == prev2
+                && prev2->loop_depth == bb->loop_depth
+                && GET_CODE (branch_target) != REG)
+         prop = prev;
+
+       /* Don't propagate when:
+          - this is a simple loop and the hint would be too far
+          - this is not a simple loop and there are 16 insns in
+          this block already
+          - the predecessor block ends in a branch that will be
+          hinted
+          - the predecessor block ends in an insn that invalidates
+          the hint */
+       if (prop
+           && prop->index >= 0
+           && (bbend = BB_END (prop))
+           && branch_addr - INSN_ADDRESSES (INSN_UID (bbend)) <
+           (simple_loop ? 600 : 16 * 4) && get_branch_target (bbend) == 0
+           && (JUMP_P (bbend) || !insn_clobbers_hbr (bbend)))
+         {
+           if (dump_file)
+             fprintf (dump_file, "propagate from %i to %i (loop depth %i) "
+                      "for %i (loop_exit %i simple_loop %i dist %i)\n",
+                      bb->index, prop->index, bb->loop_depth,
+                      INSN_UID (branch), loop_exit, simple_loop,
+                      branch_addr - INSN_ADDRESSES (INSN_UID (bbend)));
+
+           spu_bb_info[prop->index].prop_jump = branch;
+           spu_bb_info[prop->index].bb = bb;
+         }
+       else if (next && branch_addr - next_addr >= spu_hint_dist)
+         {
+           if (dump_file)
+             fprintf (dump_file, "hint for %i in block %i before %i\n",
+                      INSN_UID (branch), bb->index, INSN_UID (next));
+           spu_emit_branch_hint (next, branch, branch_target,
+                                 branch_addr - next_addr);
+         }
+       branch = 0;
+      }
+  }
+  free (spu_bb_info);
+}
+\f
+/* Emit a nop for INSN such that the two will dual issue.  This assumes
+   INSN is 8-byte aligned.  When INSN is inline asm we emit an lnop.
+   We check for TImode to handle a MULTI1 insn which has dual issued its
+   first instruction.  get_pipe returns -1 for MULTI0, inline asm, or
+   ADDR_VEC insns. */
+static void
+emit_nop_for_insn (rtx insn)
+{
+  int p;
+  rtx new_insn;
+  p = get_pipe (insn);
+  if (p == 1 && GET_MODE (insn) == TImode)
+    {
+      new_insn = emit_insn_before (gen_nopn (GEN_INT (127)), insn);
+      PUT_MODE (new_insn, TImode);
+      PUT_MODE (insn, VOIDmode);
+    }
+  else
+    new_insn = emit_insn_after (gen_lnop (), insn);
+}
+
+/* Insert nops in basic blocks to meet dual issue alignment
+   requirements. */
+static void
+insert_nops (void)
+{
+  rtx insn, next_insn, prev_insn;
+  int length;
+  int addr;
+
+  /* This sets up INSN_ADDRESSES. */
+  shorten_branches (get_insns ());
+
+  /* Keep track of length added by nops. */
+  length = 0;
+
+  prev_insn = 0;
+  for (insn = get_insns (); insn; insn = next_insn)
+    {
+      next_insn = next_active_insn (insn);
+      addr = INSN_ADDRESSES (INSN_UID (insn));
+      if (GET_MODE (insn) == TImode
+         && next_insn
+         && GET_MODE (next_insn) != TImode
+         && ((addr + length) & 7) != 0)
+       {
+         /* prev_insn will always be set because the first insn is
+            always 8-byte aligned. */
+         emit_nop_for_insn (prev_insn);
+         length += 4;
+       }
+      prev_insn = insn;
+    }
+}
+
+static void
+spu_machine_dependent_reorg (void)
+{
+  if (optimize > 0)
+    {
+      if (TARGET_BRANCH_HINTS)
+       insert_branch_hints ();
+      insert_nops ();
+    }
+}
+\f
+
+/* Insn scheduling routines, primarily for dual issue. */
+static int
+spu_sched_issue_rate (void)
+{
+  return 2;
+}
+
+static int
+spu_sched_variable_issue (FILE * dump ATTRIBUTE_UNUSED,
+                         int verbose ATTRIBUTE_UNUSED, rtx insn,
+                         int can_issue_more)
+{
+  if (GET_CODE (PATTERN (insn)) != USE
+      && GET_CODE (PATTERN (insn)) != CLOBBER
+      && get_pipe (insn) != -2)
+    can_issue_more--;
+  return can_issue_more;
+}
+
+static int
+get_pipe (rtx insn)
+{
+  enum attr_type t;
+  /* Handle inline asm */
+  if (INSN_CODE (insn) == -1)
+    return -1;
+  t = get_attr_type (insn);
+  switch (t)
+    {
+    case TYPE_CONVERT:
+      return -2;
+    case TYPE_MULTI0:
+      return -1;
+
+    case TYPE_FX2:
+    case TYPE_FX3:
+    case TYPE_SPR:
+    case TYPE_NOP:
+    case TYPE_FXB:
+    case TYPE_FPD:
+    case TYPE_FP6:
+    case TYPE_FP7:
+    case TYPE_IPREFETCH:
+      return 0;
+
+    case TYPE_LNOP:
+    case TYPE_SHUF:
+    case TYPE_LOAD:
+    case TYPE_STORE:
+    case TYPE_BR:
+    case TYPE_MULTI1:
+    case TYPE_HBR:
+      return 1;
+    default:
+      abort ();
+    }
+}
+
+static int
+spu_sched_adjust_priority (rtx insn, int pri)
+{
+  int p = get_pipe (insn);
+  /* Schedule UNSPEC_CONVERT's early so they have less effect on
+   * scheduling.  */
+  if (GET_CODE (PATTERN (insn)) == USE
+      || GET_CODE (PATTERN (insn)) == CLOBBER
+      || p == -2)
+    return pri + 100; 
+  /* Schedule pipe0 insns early for greedier dual issue. */
+  if (p != 1)
+    return pri + 50;
+  return pri;
+}
+
+/* INSN is dependent on DEP_INSN. */
+static int
+spu_sched_adjust_cost (rtx insn, rtx link ATTRIBUTE_UNUSED,
+                      rtx dep_insn ATTRIBUTE_UNUSED, int cost)
+{
+  if (GET_CODE (insn) == CALL_INSN)
+    return cost - 2;
+  /* The dfa scheduler sets cost to 0 for all anti-dependencies and the
+     scheduler makes every insn in a block anti-dependent on the final
+     jump_insn.  We adjust here so higher cost insns will get scheduled
+     earlier. */
+  if (GET_CODE (insn) == JUMP_INSN && REG_NOTE_KIND (link) == REG_DEP_ANTI)
+    return INSN_COST (dep_insn) - 3;
+  return cost;
+}
+\f
+/* Create a CONST_DOUBLE from a string.  */
+struct rtx_def *
+spu_float_const (const char *string, enum machine_mode mode)
+{
+  REAL_VALUE_TYPE value;
+  value = REAL_VALUE_ATOF (string, mode);
+  return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
+}
+
+/* Given a (CONST (PLUS (SYMBOL_REF) (CONST_INT))) return TRUE when the
+   CONST_INT fits constraint 'K', i.e., is small. */
+int
+legitimate_const (rtx x, int aligned)
+{
+  /* We can never know if the resulting address fits in 18 bits and can be
+     loaded with ila.  Instead we should use the HI and LO relocations to
+     load a 32 bit address. */
+  rtx sym, cst;
+
+  gcc_assert (GET_CODE (x) == CONST);
+
+  if (GET_CODE (XEXP (x, 0)) != PLUS)
+    return 0;
+  sym = XEXP (XEXP (x, 0), 0);
+  cst = XEXP (XEXP (x, 0), 1);
+  if (GET_CODE (sym) != SYMBOL_REF || GET_CODE (cst) != CONST_INT)
+    return 0;
+  if (aligned && ((INTVAL (cst) & 15) != 0 || !ALIGNED_SYMBOL_REF_P (sym)))
+    return 0;
+  return satisfies_constraint_K (cst);
+}
+
+int
+spu_constant_address_p (rtx x)
+{
+  return (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF
+         || GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST
+         || GET_CODE (x) == HIGH);
+}
+
+static enum spu_immediate
+which_immediate_load (HOST_WIDE_INT val)
+{
+  gcc_assert (val == trunc_int_for_mode (val, SImode));
+
+  if (val >= -0x8000 && val <= 0x7fff)
+    return SPU_IL;
+  if (val >= 0 && val <= 0x3ffff)
+    return SPU_ILA;
+  if ((val & 0xffff) == ((val >> 16) & 0xffff))
+    return SPU_ILH;
+  if ((val & 0xffff) == 0)
+    return SPU_ILHU;
+
+  return SPU_NONE;
+}
+
+int
+immediate_load_p (rtx op, enum machine_mode mode)
+{
+  HOST_WIDE_INT val;
+  unsigned char arr[16];
+  int i, j;
+  if (GET_MODE (op) != VOIDmode)
+    mode = GET_MODE (op);
+
+  gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
+             || GET_CODE (op) == CONST_VECTOR);
+
+  /* V4SI with all identical symbols is valid. */
+  if (mode == V4SImode
+      && GET_CODE (CONST_VECTOR_ELT (op, 0)) == SYMBOL_REF)
+    return !TARGET_LARGE_MEM && !flag_pic
+          && CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)
+          && CONST_VECTOR_ELT (op, 1) == CONST_VECTOR_ELT (op, 2)
+          && CONST_VECTOR_ELT (op, 2) == CONST_VECTOR_ELT (op, 3);
+
+  constant_to_array (mode, op, arr);
+
+  /* Check that bytes are repeated. */
+  for (i = 4; i < 16; i += 4)
+    for (j = 0; j < 4; j++)
+      if (arr[j] != arr[i + j])
+       return 0;
+
+  val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+  val = trunc_int_for_mode (val, SImode);
+
+  return which_immediate_load (val) != SPU_NONE;
+}
+
+static enum spu_immediate
+which_logical_immediate (HOST_WIDE_INT val)
+{
+  gcc_assert (val == trunc_int_for_mode (val, SImode));
+
+  if (val >= -0x200 && val <= 0x1ff)
+    return SPU_ORI;
+  if (val >= 0 && val <= 0xffff)
+    return SPU_IOHL;
+  if ((val & 0xffff) == ((val >> 16) & 0xffff))
+    {
+      val = trunc_int_for_mode (val, HImode);
+      if (val >= -0x200 && val <= 0x1ff)
+       return SPU_ORHI;
+      if ((val & 0xff) == ((val >> 8) & 0xff))
+       {
+         val = trunc_int_for_mode (val, QImode);
+         if (val >= -0x200 && val <= 0x1ff)
+           return SPU_ORBI;
+       }
+    }
+  return SPU_NONE;
+}
+
+int
+logical_immediate_p (rtx op, enum machine_mode mode)
+{
+  HOST_WIDE_INT val;
+  unsigned char arr[16];
+  int i, j;
+
+  gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
+             || GET_CODE (op) == CONST_VECTOR);
+
+  if (GET_MODE (op) != VOIDmode)
+    mode = GET_MODE (op);
+
+  constant_to_array (mode, op, arr);
+
+  /* Check that bytes are repeated. */
+  for (i = 4; i < 16; i += 4)
+    for (j = 0; j < 4; j++)
+      if (arr[j] != arr[i + j])
+       return 0;
+
+  val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+  val = trunc_int_for_mode (val, SImode);
+
+  i = which_logical_immediate (val);
+  return i != SPU_NONE && i != SPU_IOHL;
+}
+
+int
+iohl_immediate_p (rtx op, enum machine_mode mode)
+{
+  HOST_WIDE_INT val;
+  unsigned char arr[16];
+  int i, j;
+
+  gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
+             || GET_CODE (op) == CONST_VECTOR);
+
+  if (GET_MODE (op) != VOIDmode)
+    mode = GET_MODE (op);
+
+  constant_to_array (mode, op, arr);
+
+  /* Check that bytes are repeated. */
+  for (i = 4; i < 16; i += 4)
+    for (j = 0; j < 4; j++)
+      if (arr[j] != arr[i + j])
+       return 0;
+
+  val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+  val = trunc_int_for_mode (val, SImode);
+
+  return val >= 0 && val <= 0xffff;
+}
+
+int
+arith_immediate_p (rtx op, enum machine_mode mode,
+                  HOST_WIDE_INT low, HOST_WIDE_INT high)
+{
+  HOST_WIDE_INT val;
+  unsigned char arr[16];
+  int bytes, i, j;
+
+  gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
+             || GET_CODE (op) == CONST_VECTOR);
+
+  if (GET_MODE (op) != VOIDmode)
+    mode = GET_MODE (op);
+
+  constant_to_array (mode, op, arr);
+
+  if (VECTOR_MODE_P (mode))
+    mode = GET_MODE_INNER (mode);
+
+  bytes = GET_MODE_SIZE (mode);
+  mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
+
+  /* Check that bytes are repeated. */
+  for (i = bytes; i < 16; i += bytes)
+    for (j = 0; j < bytes; j++)
+      if (arr[j] != arr[i + j])
+       return 0;
+
+  val = arr[0];
+  for (j = 1; j < bytes; j++)
+    val = (val << 8) | arr[j];
+
+  val = trunc_int_for_mode (val, mode);
+
+  return val >= low && val <= high;
+}
+
+/* We accept:
+   - any 32 bit constant (SImode, SFmode)
+   - any constant that can be generated with fsmbi (any mode)
+   - a 64 bit constant where the high and low bits are identical
+     (DImode, DFmode)
+   - a 128 bit constant where the four 32 bit words match. */
+int
+spu_legitimate_constant_p (rtx x)
+{
+  unsigned char arr[16];
+  int i, j;
+
+  if (GET_CODE (x) == HIGH
+      || GET_CODE (x) == CONST
+      || GET_CODE (x) == SYMBOL_REF
+      || GET_CODE (x) == LABEL_REF)
+    return 1;
+
+  if (fsmbi_const_p (x))
+    return 1;
+
+  if (GET_CODE (x) == CONST_INT)
+    return (INTVAL (x) >= -0x80000000ll && INTVAL (x) <= 0x7fffffffll)
+      || ((INTVAL (x) >> 32) & 0xffffffffll) == (INTVAL (x) & 0xffffffffll);
+
+  if (GET_MODE (x) == SFmode)
+    return 1;
+
+  if (GET_MODE (x) == DFmode)
+    {
+      HOST_WIDE_INT val = const_double_to_hwint (x);
+      return ((val >> 32) & 0xffffffffll) == (val & 0xffffffffll);
+    }
+
+  /* V4SI with all identical symbols is valid. */
+  if (GET_MODE (x) == V4SImode
+      && (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF
+         || GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF
+         || GET_CODE (CONST_VECTOR_ELT (x, 0)) == CONST
+         || GET_CODE (CONST_VECTOR_ELT (x, 0)) == HIGH))
+    return CONST_VECTOR_ELT (x, 0) == CONST_VECTOR_ELT (x, 1)
+          && CONST_VECTOR_ELT (x, 1) == CONST_VECTOR_ELT (x, 2)
+          && CONST_VECTOR_ELT (x, 2) == CONST_VECTOR_ELT (x, 3);
+
+  if (VECTOR_MODE_P (GET_MODE (x)))
+    for (i = 0; i < GET_MODE_NUNITS (GET_MODE (x)); i++)
+      if (GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_INT
+         && GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_DOUBLE)
+       return 0;
+
+  constant_to_array (SImode, x, arr);
+
+  /* Check that bytes are repeated. */
+  for (i = 4; i < 16; i += 4)
+    for (j = 0; j < 4; j++)
+      if (arr[j] != arr[i + j])
+       return 0;
+
+  return 1;
+}
+
+/* Valid address are:
+   - symbol_ref, label_ref, const
+   - reg
+   - reg + const, where either reg or const is 16 byte aligned
+   - reg + reg, alignment doesn't matter
+  The alignment matters in the reg+const case because lqd and stqd
+  ignore the 4 least significant bits of the const.  (TODO: It might be
+  preferable to allow any alignment and fix it up when splitting.) */
+int
+spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
+                       rtx x, int reg_ok_strict)
+{
+  if (mode == TImode && GET_CODE (x) == AND
+      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT) -16)
+    x = XEXP (x, 0);
+  switch (GET_CODE (x))
+    {
+    case SYMBOL_REF:
+    case LABEL_REF:
+      return !TARGET_LARGE_MEM;
+
+    case CONST:
+      return !TARGET_LARGE_MEM && legitimate_const (x, 1);
+
+    case CONST_INT:
+      return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff;
+
+    case SUBREG:
+      x = XEXP (x, 0);
+      gcc_assert (GET_CODE (x) == REG);
+
+    case REG:
+      return INT_REG_OK_FOR_BASE_P (x, reg_ok_strict);
+
+    case PLUS:
+    case LO_SUM:
+      {
+       rtx op0 = XEXP (x, 0);
+       rtx op1 = XEXP (x, 1);
+       if (GET_CODE (op0) == SUBREG)
+         op0 = XEXP (op0, 0);
+       if (GET_CODE (op1) == SUBREG)
+         op1 = XEXP (op1, 0);
+       /* We can't just accept any aligned register because CSE can
+          change it to a register that is not marked aligned and then
+          recog will fail.   So we only accept frame registers because
+          they will only be changed to other frame registers. */
+       if (GET_CODE (op0) == REG
+           && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict)
+           && GET_CODE (op1) == CONST_INT
+           && INTVAL (op1) >= -0x2000
+           && INTVAL (op1) <= 0x1fff
+           && (REGNO_PTR_FRAME_P (REGNO (op0)) || (INTVAL (op1) & 15) == 0))
+         return 1;
+       if (GET_CODE (op0) == REG
+           && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict)
+           && GET_CODE (op1) == REG
+           && INT_REG_OK_FOR_INDEX_P (op1, reg_ok_strict))
+         return 1;
+      }
+      break;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+/* When the address is reg + const_int, force the const_int into a
+   regiser. */
+rtx
+spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+                       enum machine_mode mode)
+{
+  rtx op0, op1;
+  /* Make sure both operands are registers.  */
+  if (GET_CODE (x) == PLUS)
+    {
+      op0 = XEXP (x, 0);
+      op1 = XEXP (x, 1);
+      if (ALIGNED_SYMBOL_REF_P (op0))
+       {
+         op0 = force_reg (Pmode, op0);
+         mark_reg_pointer (op0, 128);
+       }
+      else if (GET_CODE (op0) != REG)
+       op0 = force_reg (Pmode, op0);
+      if (ALIGNED_SYMBOL_REF_P (op1))
+       {
+         op1 = force_reg (Pmode, op1);
+         mark_reg_pointer (op1, 128);
+       }
+      else if (GET_CODE (op1) != REG)
+       op1 = force_reg (Pmode, op1);
+      x = gen_rtx_PLUS (Pmode, op0, op1);
+      if (spu_legitimate_address (mode, x, 0))
+       return x;
+    }
+  return NULL_RTX;
+}
+
+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
+   struct attribute_spec.handler.  */
+static tree
+spu_handle_fndecl_attribute (tree * node,
+                            tree name,
+                            tree args ATTRIBUTE_UNUSED,
+                            int flags ATTRIBUTE_UNUSED, bool * no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+    {
+      warning (0, "`%s' attribute only applies to functions",
+              IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
+/* Handle the "vector" attribute.  */
+static tree
+spu_handle_vector_attribute (tree * node, tree name,
+                            tree args ATTRIBUTE_UNUSED,
+                            int flags ATTRIBUTE_UNUSED, bool * no_add_attrs)
+{
+  tree type = *node, result = NULL_TREE;
+  enum machine_mode mode;
+  int unsigned_p;
+
+  while (POINTER_TYPE_P (type)
+        || TREE_CODE (type) == FUNCTION_TYPE
+        || TREE_CODE (type) == METHOD_TYPE || TREE_CODE (type) == ARRAY_TYPE)
+    type = TREE_TYPE (type);
+
+  mode = TYPE_MODE (type);
+
+  unsigned_p = TYPE_UNSIGNED (type);
+  switch (mode)
+    {
+    case DImode:
+      result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
+      break;
+    case SImode:
+      result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
+      break;
+    case HImode:
+      result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
+      break;
+    case QImode:
+      result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
+      break;
+    case SFmode:
+      result = V4SF_type_node;
+      break;
+    case DFmode:
+      result = V2DF_type_node;
+      break;
+    default:
+      break;
+    }
+
+  /* Propagate qualifiers attached to the element type
+     onto the vector type.  */
+  if (result && result != type && TYPE_QUALS (type))
+    result = build_qualified_type (result, TYPE_QUALS (type));
+
+  *no_add_attrs = true;                /* No need to hang on to the attribute.  */
+
+  if (!result)
+    warning (0, "`%s' attribute ignored", IDENTIFIER_POINTER (name));
+  else
+    *node = reconstruct_complex_type (*node, result);
+
+  return NULL_TREE;
+}
+
+/* Return non-zero if FUNC is a naked function.  */
+static int
+spu_naked_function_p (tree func)
+{
+  tree a;
+
+  if (TREE_CODE (func) != FUNCTION_DECL)
+    abort ();
+
+  a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
+  return a != NULL_TREE;
+}
+
+int
+spu_initial_elimination_offset (int from, int to)
+{
+  int saved_regs_size = spu_saved_regs_size ();
+  int sp_offset = 0;
+  if (!current_function_is_leaf || current_function_outgoing_args_size
+      || get_frame_size () || saved_regs_size)
+    sp_offset = STACK_POINTER_OFFSET;
+  if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+    return (sp_offset + current_function_outgoing_args_size);
+  else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
+    return 0;
+  else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+    return sp_offset + current_function_outgoing_args_size
+      + get_frame_size () + saved_regs_size + STACK_POINTER_OFFSET;
+  else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
+    return get_frame_size () + saved_regs_size + sp_offset;
+  return 0;
+}
+
+rtx
+spu_function_value (tree type, tree func ATTRIBUTE_UNUSED)
+{
+  enum machine_mode mode = TYPE_MODE (type);
+  int byte_size = ((mode == BLKmode)
+                  ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
+
+  /* Make sure small structs are left justified in a register. */
+  if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
+      && byte_size <= UNITS_PER_WORD * MAX_REGISTER_RETURN && byte_size > 0)
+    {
+      enum machine_mode smode;
+      rtvec v;
+      int i;
+      int nregs = (byte_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+      int n = byte_size / UNITS_PER_WORD;
+      v = rtvec_alloc (nregs);
+      for (i = 0; i < n; i++)
+       {
+         RTVEC_ELT (v, i) = gen_rtx_EXPR_LIST (VOIDmode,
+                                               gen_rtx_REG (TImode,
+                                                            FIRST_RETURN_REGNUM
+                                                            + i),
+                                               GEN_INT (UNITS_PER_WORD * i));
+         byte_size -= UNITS_PER_WORD;
+       }
+
+      if (n < nregs)
+       {
+         if (byte_size < 4)
+           byte_size = 4;
+         smode =
+           smallest_mode_for_size (byte_size * BITS_PER_UNIT, MODE_INT);
+         RTVEC_ELT (v, n) =
+           gen_rtx_EXPR_LIST (VOIDmode,
+                              gen_rtx_REG (smode, FIRST_RETURN_REGNUM + n),
+                              GEN_INT (UNITS_PER_WORD * n));
+       }
+      return gen_rtx_PARALLEL (mode, v);
+    }
+  return gen_rtx_REG (mode, FIRST_RETURN_REGNUM);
+}
+
+rtx
+spu_function_arg (CUMULATIVE_ARGS cum,
+                 enum machine_mode mode,
+                 tree type, int named ATTRIBUTE_UNUSED)
+{
+  int byte_size;
+
+  if (cum >= MAX_REGISTER_ARGS)
+    return 0;
+
+  byte_size = ((mode == BLKmode)
+              ? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
+
+  /* The ABI does not allow parameters to be passed partially in
+     reg and partially in stack. */
+  if ((cum + (byte_size + 15) / 16) > MAX_REGISTER_ARGS)
+    return 0;
+
+  /* Make sure small structs are left justified in a register. */
+  if ((mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
+      && byte_size < UNITS_PER_WORD && byte_size > 0)
+    {
+      enum machine_mode smode;
+      rtx gr_reg;
+      if (byte_size < 4)
+       byte_size = 4;
+      smode = smallest_mode_for_size (byte_size * BITS_PER_UNIT, MODE_INT);
+      gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
+                                 gen_rtx_REG (smode, FIRST_ARG_REGNUM + cum),
+                                 const0_rtx);
+      return gen_rtx_PARALLEL (mode, gen_rtvec (1, gr_reg));
+    }
+  else
+    return gen_rtx_REG (mode, FIRST_ARG_REGNUM + cum);
+}
+
+/* Variable sized types are passed by reference.  */
+static bool
+spu_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,
+                      enum machine_mode mode ATTRIBUTE_UNUSED,
+                      tree type, bool named ATTRIBUTE_UNUSED)
+{
+  return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
+}
+\f
+
+/* Var args. */
+
+/* Create and return the va_list datatype.
+
+   On SPU, va_list is an array type equivalent to
+
+      typedef struct __va_list_tag
+        {
+            void *__args __attribute__((__aligned(16)));
+            void *__skip __attribute__((__aligned(16)));
+            
+        } va_list[1];
+
+   wheare __args points to the arg that will be returned by the next
+   va_arg(), and __skip points to the previous stack frame such that
+   when __args == __skip we should advance __args by 32 bytes. */
+static tree
+spu_build_builtin_va_list (void)
+{
+  tree f_args, f_skip, record, type_decl;
+  bool owp;
+
+  record = (*lang_hooks.types.make_type) (RECORD_TYPE);
+
+  type_decl =
+    build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+
+  f_args = build_decl (FIELD_DECL, get_identifier ("__args"), ptr_type_node);
+  f_skip = build_decl (FIELD_DECL, get_identifier ("__skip"), ptr_type_node);
+
+  DECL_FIELD_CONTEXT (f_args) = record;
+  DECL_ALIGN (f_args) = 128;
+  DECL_USER_ALIGN (f_args) = 1;
+
+  DECL_FIELD_CONTEXT (f_skip) = record;
+  DECL_ALIGN (f_skip) = 128;
+  DECL_USER_ALIGN (f_skip) = 1;
+
+  TREE_CHAIN (record) = type_decl;
+  TYPE_NAME (record) = type_decl;
+  TYPE_FIELDS (record) = f_args;
+  TREE_CHAIN (f_args) = f_skip;
+
+  /* We know this is being padded and we want it too.  It is an internal
+     type so hide the warnings from the user. */
+  owp = warn_padded;
+  warn_padded = false;
+
+  layout_type (record);
+
+  warn_padded = owp;
+
+  /* The correct type is an array type of one element.  */
+  return build_array_type (record, build_index_type (size_zero_node));
+}
+
+/* Implement va_start by filling the va_list structure VALIST.
+   NEXTARG points to the first anonymous stack argument.
+
+   The following global variables are used to initialize
+   the va_list structure:
+
+     current_function_args_info;
+       the CUMULATIVE_ARGS for this function
+
+     current_function_arg_offset_rtx:
+       holds the offset of the first anonymous stack argument
+       (relative to the virtual arg pointer).  */
+
+void
+spu_va_start (tree valist, rtx nextarg)
+{
+  tree f_args, f_skip;
+  tree args, skip, t;
+
+  f_args = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+  f_skip = TREE_CHAIN (f_args);
+
+  valist = build_va_arg_indirect_ref (valist);
+  args =
+    build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE);
+  skip =
+    build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE);
+
+  /* Find the __args area.  */
+  t = make_tree (TREE_TYPE (args), nextarg);
+  if (current_function_pretend_args_size > 0)
+    t = build2 (PLUS_EXPR, TREE_TYPE (args), t,
+               build_int_cst (integer_type_node, -STACK_POINTER_OFFSET));
+  t = build2 (MODIFY_EXPR, TREE_TYPE (args), args, t);
+  TREE_SIDE_EFFECTS (t) = 1;
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  /* Find the __skip area.  */
+  t = make_tree (TREE_TYPE (skip), virtual_incoming_args_rtx);
+  t = build2 (PLUS_EXPR, TREE_TYPE (skip), t,
+             build_int_cst (integer_type_node,
+                            (current_function_pretend_args_size
+                             - STACK_POINTER_OFFSET)));
+  t = build2 (MODIFY_EXPR, TREE_TYPE (skip), skip, t);
+  TREE_SIDE_EFFECTS (t) = 1;
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+}
+
+/* Gimplify va_arg by updating the va_list structure 
+   VALIST as required to retrieve an argument of type
+   TYPE, and returning that argument. 
+   
+   ret = va_arg(VALIST, TYPE);
+
+   generates code equivalent to:
+   
+    paddedsize = (sizeof(TYPE) + 15) & -16;
+    if (VALIST.__args + paddedsize > VALIST.__skip
+       && VALIST.__args <= VALIST.__skip)
+      addr = VALIST.__skip + 32;
+    else
+      addr = VALIST.__args;
+    VALIST.__args = addr + paddedsize;
+    ret = *(TYPE *)addr;
+ */
+static tree
+spu_gimplify_va_arg_expr (tree valist, tree type, tree * pre_p,
+                         tree * post_p ATTRIBUTE_UNUSED)
+{
+  tree f_args, f_skip;
+  tree args, skip;
+  HOST_WIDE_INT size, rsize;
+  tree paddedsize, addr, tmp;
+  bool pass_by_reference_p;
+
+  f_args = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+  f_skip = TREE_CHAIN (f_args);
+
+  valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
+  args =
+    build3 (COMPONENT_REF, TREE_TYPE (f_args), valist, f_args, NULL_TREE);
+  skip =
+    build3 (COMPONENT_REF, TREE_TYPE (f_skip), valist, f_skip, NULL_TREE);
+
+  addr = create_tmp_var (ptr_type_node, "va_arg");
+  DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
+
+  /* if an object is dynamically sized, a pointer to it is passed
+     instead of the object itself. */
+  pass_by_reference_p = spu_pass_by_reference (NULL, TYPE_MODE (type), type,
+                                              false);
+  if (pass_by_reference_p)
+    type = build_pointer_type (type);
+  size = int_size_in_bytes (type);
+  rsize = ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD) * UNITS_PER_WORD;
+
+  /* build conditional expression to calculate addr. The expression
+     will be gimplified later. */
+  paddedsize = fold_convert (ptr_type_node, size_int (rsize));
+  tmp = build2 (PLUS_EXPR, ptr_type_node, args, paddedsize);
+  tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
+               build2 (GT_EXPR, boolean_type_node, tmp, skip),
+               build2 (LE_EXPR, boolean_type_node, args, skip));
+
+  tmp = build3 (COND_EXPR, ptr_type_node, tmp,
+               build2 (PLUS_EXPR, ptr_type_node, skip,
+                       fold_convert (ptr_type_node, size_int (32))), args);
+
+  tmp = build2 (MODIFY_EXPR, ptr_type_node, addr, tmp);
+  gimplify_and_add (tmp, pre_p);
+
+  /* update VALIST.__args */
+  tmp = build2 (PLUS_EXPR, ptr_type_node, addr, paddedsize);
+  tmp = build2 (MODIFY_EXPR, TREE_TYPE (args), args, tmp);
+  gimplify_and_add (tmp, pre_p);
+
+  addr = fold_convert (build_pointer_type (type), addr);
+
+  if (pass_by_reference_p)
+    addr = build_va_arg_indirect_ref (addr);
+
+  return build_va_arg_indirect_ref (addr);
+}
+
+/* Save parameter registers starting with the register that corresponds
+   to the first unnamed parameters.  If the first unnamed parameter is
+   in the stack then save no registers.  Set pretend_args_size to the
+   amount of space needed to save the registers. */
+void
+spu_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode,
+                           tree type, int *pretend_size, int no_rtl)
+{
+  if (!no_rtl)
+    {
+      rtx tmp;
+      int regno;
+      int offset;
+      int ncum = *cum;
+
+      /* cum currently points to the last named argument, we want to
+         start at the next argument. */
+      FUNCTION_ARG_ADVANCE (ncum, mode, type, 1);
+
+      offset = -STACK_POINTER_OFFSET;
+      for (regno = ncum; regno < MAX_REGISTER_ARGS; regno++)
+       {
+         tmp = gen_frame_mem (V4SImode,
+                              plus_constant (virtual_incoming_args_rtx,
+                                             offset));
+         emit_move_insn (tmp,
+                         gen_rtx_REG (V4SImode, FIRST_ARG_REGNUM + regno));
+         offset += 16;
+       }
+      *pretend_size = offset + STACK_POINTER_OFFSET;
+    }
+}
+\f
+void
+spu_conditional_register_usage (void)
+{
+  if (flag_pic)
+    {
+      fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
+      call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
+    }
+  global_regs[INTR_REGNUM] = 1;
+}
+
+/* This is called to decide when we can simplify a load instruction.  We
+   must only return true for registers which we know will always be
+   aligned.  Taking into account that CSE might replace this reg with
+   another one that has not been marked aligned.  
+   So this is really only true for frame, stack and virtual registers,
+   which we know are always aligned and should not be adversly effected
+   by CSE. */
+static int
+regno_aligned_for_load (int regno)
+{
+  return regno == FRAME_POINTER_REGNUM
+    || regno == HARD_FRAME_POINTER_REGNUM
+    || regno == STACK_POINTER_REGNUM
+    || (regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER);
+}
+
+/* Return TRUE when mem is known to be 16-byte aligned. */
+int
+aligned_mem_p (rtx mem)
+{
+  if (MEM_ALIGN (mem) >= 128)
+    return 1;
+  if (GET_MODE_SIZE (GET_MODE (mem)) >= 16)
+    return 1;
+  if (GET_CODE (XEXP (mem, 0)) == PLUS)
+    {
+      rtx p0 = XEXP (XEXP (mem, 0), 0);
+      rtx p1 = XEXP (XEXP (mem, 0), 1);
+      if (regno_aligned_for_load (REGNO (p0)))
+       {
+         if (GET_CODE (p1) == REG && regno_aligned_for_load (REGNO (p1)))
+           return 1;
+         if (GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15) == 0)
+           return 1;
+       }
+    }
+  else if (GET_CODE (XEXP (mem, 0)) == REG)
+    {
+      if (regno_aligned_for_load (REGNO (XEXP (mem, 0))))
+       return 1;
+    }
+  else if (ALIGNED_SYMBOL_REF_P (XEXP (mem, 0)))
+    return 1;
+  else if (GET_CODE (XEXP (mem, 0)) == CONST)
+    {
+      rtx p0 = XEXP (XEXP (XEXP (mem, 0), 0), 0);
+      rtx p1 = XEXP (XEXP (XEXP (mem, 0), 0), 1);
+      if (GET_CODE (p0) == SYMBOL_REF
+         && GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15) == 0)
+       return 1;
+    }
+  return 0;
+}
+
+/* Return TRUE if we are certain the mem refers to a complete object
+   which is both 16-byte aligned and padded to a 16-byte boundary.  This
+   would make it safe to store with a single instruction. 
+   We guarantee the alignment and padding for static objects by aligning
+   all of them to 16-bytes. (DATA_ALIGNMENT and CONSTANT_ALIGNMENT.)
+   FIXME: We currently cannot guarantee this for objects on the stack
+   because assign_parm_setup_stack calls assign_stack_local with the
+   alignment of the parameter mode and in that case the alignment never
+   gets adjusted by LOCAL_ALIGNMENT. */
+static int
+store_with_one_insn_p (rtx mem)
+{
+  rtx addr = XEXP (mem, 0);
+  if (GET_MODE (mem) == BLKmode)
+    return 0;
+  /* Only static objects. */
+  if (GET_CODE (addr) == SYMBOL_REF)
+    {
+      /* We use the associated declaration to make sure the access is
+         refering to the whole object.
+         We check both MEM_EXPR and and SYMBOL_REF_DECL.  I'm not sure
+         if it is necessary.  Will there be cases where one exists, and
+         the other does not?  Will there be cases where both exist, but
+         have different types?  */
+      tree decl = MEM_EXPR (mem);
+      if (decl
+         && TREE_CODE (decl) == VAR_DECL
+         && GET_MODE (mem) == TYPE_MODE (TREE_TYPE (decl)))
+       return 1;
+      decl = SYMBOL_REF_DECL (addr);
+      if (decl
+         && TREE_CODE (decl) == VAR_DECL
+         && GET_MODE (mem) == TYPE_MODE (TREE_TYPE (decl)))
+       return 1;
+    }
+  return 0;
+}
+
+int
+spu_expand_mov (rtx * ops, enum machine_mode mode)
+{
+  if (GET_CODE (ops[0]) == SUBREG && !valid_subreg (ops[0]))
+    abort ();
+
+  if (GET_CODE (ops[1]) == SUBREG && !valid_subreg (ops[1]))
+    {
+      rtx from = SUBREG_REG (ops[1]);
+      enum machine_mode imode = GET_MODE (from);
+
+      gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
+                 && GET_MODE_CLASS (imode) == MODE_INT
+                 && subreg_lowpart_p (ops[1]));
+
+      if (GET_MODE_SIZE (imode) < 4)
+       {
+         from = gen_rtx_SUBREG (SImode, from, 0);
+         imode = SImode;
+       }
+
+      if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (imode))
+       {
+         enum insn_code icode = trunc_optab->handlers[mode][imode].insn_code;
+         emit_insn (GEN_FCN (icode) (ops[0], from));
+       }
+      else
+       emit_insn (gen_extend_insn (ops[0], from, mode, imode, 1));
+      return 1;
+    }
+
+  /* At least one of the operands needs to be a register. */
+  if ((reload_in_progress | reload_completed) == 0
+      && !register_operand (ops[0], mode) && !register_operand (ops[1], mode))
+    {
+      rtx temp = force_reg (mode, ops[1]);
+      emit_move_insn (ops[0], temp);
+      return 1;
+    }
+  if (reload_in_progress || reload_completed)
+    {
+      enum machine_mode mode = GET_MODE (ops[0]);
+      if (GET_CODE (ops[1]) == CONST_INT
+         && (mode == DImode || mode == TImode)
+         && ((INTVAL (ops[1]) >> 32) & 0xffffffffll) !=
+         (INTVAL (ops[1]) & 0xffffffffll))
+       {
+         rtx mem = force_const_mem (mode, ops[1]);
+         if (TARGET_LARGE_MEM)
+           {
+             rtx addr = gen_rtx_REG (Pmode, REGNO (ops[0]));
+             emit_move_insn (addr, XEXP (mem, 0));
+             mem = replace_equiv_address (mem, addr);
+           }
+         emit_move_insn (ops[0], mem);
+         return 1;
+       }
+      else if ((GET_CODE (ops[1]) == CONST_INT
+               || GET_CODE (ops[1]) == CONST_DOUBLE
+               || GET_CODE (ops[1]) == CONST_VECTOR)
+              && !immediate_load_p (ops[1], mode)
+              && !fsmbi_const_p (ops[1]))
+       {
+         unsigned char arrlo[16];
+         unsigned char arrhi[16];
+         rtx to = ops[0], hi, lo;
+         int i;
+         constant_to_array (mode, ops[1], arrhi);
+         for (i = 0; i < 16; i += 4)
+           {
+             arrlo[i + 2] = arrhi[i + 2];
+             arrlo[i + 3] = arrhi[i + 3];
+             arrlo[i + 0] = arrlo[i + 1] = 0;
+             arrhi[i + 2] = arrhi[i + 3] = 0;
+           }
+         if (mode == SFmode)
+           {
+             to = spu_gen_subreg (SImode, ops[0]);
+             mode = SImode;
+           }
+         else if (mode == V4SFmode)
+           {
+             to = spu_gen_subreg (V4SImode, ops[0]);
+             mode = V4SImode;
+           }
+         hi = array_to_constant (mode, arrhi);
+         lo = array_to_constant (mode, arrlo);
+         emit_move_insn (to, hi);
+         emit_insn (gen_rtx_SET (VOIDmode, to, gen_rtx_IOR (mode, to, lo)));
+         return 1;
+       }
+      if ((GET_CODE (ops[1]) == CONST
+           && !legitimate_const (ops[1], 0))
+         || (TARGET_LARGE_MEM
+             && (GET_CODE (ops[1]) == CONST
+                 || GET_CODE (ops[1]) == SYMBOL_REF
+                 || GET_CODE (ops[1]) == LABEL_REF)))
+       {
+         emit_insn (gen_high (ops[0], ops[1]));
+         emit_insn (gen_low (ops[0], ops[0], ops[1]));
+         if (flag_pic)
+           {
+             rtx pic_reg = get_pic_reg ();
+             emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg));
+             current_function_uses_pic_offset_table = 1;
+           }
+         return 1;
+       }
+      if (flag_pic
+         && (GET_CODE (ops[1]) == SYMBOL_REF
+             || GET_CODE (ops[1]) == LABEL_REF
+             || GET_CODE (ops[1]) == CONST))
+       {
+         rtx pic_reg = get_pic_reg ();
+         emit_insn (gen_pic (ops[0], ops[1]));
+         emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg));
+         current_function_uses_pic_offset_table = 1;
+         return 1;
+       }
+      return 0;
+    }
+  else
+    {
+      if (GET_CODE (ops[0]) == MEM)
+       {
+         if (!spu_valid_move (ops))
+           {
+             emit_insn (gen_store (ops[0], ops[1], gen_reg_rtx (TImode),
+                                   gen_reg_rtx (TImode)));
+             return 1;
+           }
+       }
+      else if (GET_CODE (ops[1]) == MEM)
+       {
+         if (!spu_valid_move (ops))
+           {
+             emit_insn (gen_load
+                        (ops[0], ops[1], gen_reg_rtx (TImode),
+                         gen_reg_rtx (SImode)));
+             return 1;
+           }
+       }
+      /* Catch the SImode immediates greater than 0x7fffffff, and sign
+         extend them. */
+      if (GET_CODE (ops[1]) == CONST_INT)
+       {
+         HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (ops[1]), mode);
+         if (val != INTVAL (ops[1]))
+           {
+             emit_move_insn (ops[0], GEN_INT (val));
+             return 1;
+           }
+       }
+    }
+  return 0;
+}
+
+static int
+reg_align (rtx reg)
+{
+  /* For now, only frame registers are known to be aligned at all times.
+     We can't trust REGNO_POINTER_ALIGN because optimization will move
+     registers around, potentially changing an "aligned" register in an
+     address to an unaligned register, which would result in an invalid
+     address. */
+  int regno = REGNO (reg);
+  return REGNO_PTR_FRAME_P (regno) ? REGNO_POINTER_ALIGN (regno) : 1;
+}
+
+void
+spu_split_load (rtx * ops)
+{
+  enum machine_mode mode = GET_MODE (ops[0]);
+  rtx addr, load, rot, mem, p0, p1;
+  int rot_amt;
+
+  addr = XEXP (ops[1], 0);
+
+  rot = 0;
+  rot_amt = 0;
+  if (GET_CODE (addr) == PLUS)
+    {
+      /* 8 cases:
+         aligned reg   + aligned reg     => lqx
+         aligned reg   + unaligned reg   => lqx, rotqby
+         aligned reg   + aligned const   => lqd
+         aligned reg   + unaligned const => lqd, rotqbyi
+         unaligned reg + aligned reg     => lqx, rotqby
+         unaligned reg + unaligned reg   => lqx, a, rotqby (1 scratch)
+         unaligned reg + aligned const   => lqd, rotqby
+         unaligned reg + unaligned const -> not allowed by legitimate address
+       */
+      p0 = XEXP (addr, 0);
+      p1 = XEXP (addr, 1);
+      if (reg_align (p0) < 128)
+       {
+         if (GET_CODE (p1) == REG && reg_align (p1) < 128)
+           {
+             emit_insn (gen_addsi3 (ops[3], p0, p1));
+             rot = ops[3];
+           }
+         else
+           rot = p0;
+       }
+      else
+       {
+         if (GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15))
+           {
+             rot_amt = INTVAL (p1) & 15;
+             p1 = GEN_INT (INTVAL (p1) & -16);
+             addr = gen_rtx_PLUS (SImode, p0, p1);
+           }
+         else if (GET_CODE (p1) == REG && reg_align (p1) < 128)
+           rot = p1;
+       }
+    }
+  else if (GET_CODE (addr) == REG)
+    {
+      if (reg_align (addr) < 128)
+       rot = addr;
+    }
+  else if (GET_CODE (addr) == CONST)
+    {
+      if (GET_CODE (XEXP (addr, 0)) == PLUS
+         && ALIGNED_SYMBOL_REF_P (XEXP (XEXP (addr, 0), 0))
+         && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
+       {
+         rot_amt = INTVAL (XEXP (XEXP (addr, 0), 1));
+         if (rot_amt & -16)
+           addr = gen_rtx_CONST (Pmode,
+                                 gen_rtx_PLUS (Pmode,
+                                               XEXP (XEXP (addr, 0), 0),
+                                               GEN_INT (rot_amt & -16)));
+         else
+           addr = XEXP (XEXP (addr, 0), 0);
+       }
+      else
+       rot = addr;
+    }
+  else if (GET_CODE (addr) == CONST_INT)
+    {
+      rot_amt = INTVAL (addr);
+      addr = GEN_INT (rot_amt & -16);
+    }
+  else if (!ALIGNED_SYMBOL_REF_P (addr))
+    rot = addr;
+
+  if (GET_MODE_SIZE (mode) < 4)
+    rot_amt += GET_MODE_SIZE (mode) - 4;
+
+  rot_amt &= 15;
+
+  if (rot && rot_amt)
+    {
+      emit_insn (gen_addsi3 (ops[3], rot, GEN_INT (rot_amt)));
+      rot = ops[3];
+      rot_amt = 0;
+    }
+
+  load = ops[2];
+
+  addr = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16));
+  mem = change_address (ops[1], TImode, addr);
+
+  emit_insn (gen_lq_ti (load, mem));
+
+  if (rot)
+    emit_insn (gen_rotqby_ti (load, load, rot));
+  else if (rot_amt)
+    emit_insn (gen_rotlti3 (load, load, GEN_INT (rot_amt * 8)));
+
+  if (reload_completed)
+    emit_move_insn (ops[0], gen_rtx_REG (GET_MODE (ops[0]), REGNO (load)));
+  else
+    emit_insn (gen_spu_convert (ops[0], load));
+}
+
+void
+spu_split_store (rtx * ops)
+{
+  enum machine_mode mode = GET_MODE (ops[0]);
+  rtx pat = ops[2];
+  rtx reg = ops[3];
+  rtx addr, p0, p1, p1_lo, smem;
+  int aform;
+  int scalar;
+
+  addr = XEXP (ops[0], 0);
+
+  if (GET_CODE (addr) == PLUS)
+    {
+      /* 8 cases:
+         aligned reg   + aligned reg     => lqx, c?x, shuf, stqx
+         aligned reg   + unaligned reg   => lqx, c?x, shuf, stqx
+         aligned reg   + aligned const   => lqd, c?d, shuf, stqx
+         aligned reg   + unaligned const => lqd, c?d, shuf, stqx
+         unaligned reg + aligned reg     => lqx, c?x, shuf, stqx
+         unaligned reg + unaligned reg   => lqx, c?x, shuf, stqx
+         unaligned reg + aligned const   => lqd, c?d, shuf, stqx
+         unaligned reg + unaligned const -> not allowed by legitimate address
+       */
+      aform = 0;
+      p0 = XEXP (addr, 0);
+      p1 = p1_lo = XEXP (addr, 1);
+      if (GET_CODE (p0) == REG && GET_CODE (p1) == CONST_INT)
+       {
+         p1_lo = GEN_INT (INTVAL (p1) & 15);
+         p1 = GEN_INT (INTVAL (p1) & -16);
+         addr = gen_rtx_PLUS (SImode, p0, p1);
+       }
+    }
+  else if (GET_CODE (addr) == REG)
+    {
+      aform = 0;
+      p0 = addr;
+      p1 = p1_lo = const0_rtx;
+    }
+  else
+    {
+      aform = 1;
+      p0 = gen_rtx_REG (SImode, STACK_POINTER_REGNUM);
+      p1 = 0;                  /* aform doesn't use p1 */
+      p1_lo = addr;
+      if (ALIGNED_SYMBOL_REF_P (addr))
+       p1_lo = const0_rtx;
+      else if (GET_CODE (addr) == CONST)
+       {
+         if (GET_CODE (XEXP (addr, 0)) == PLUS
+             && ALIGNED_SYMBOL_REF_P (XEXP (XEXP (addr, 0), 0))
+             && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
+           {
+             HOST_WIDE_INT v = INTVAL (XEXP (XEXP (addr, 0), 1));
+             if ((v & -16) != 0)
+               addr = gen_rtx_CONST (Pmode,
+                                     gen_rtx_PLUS (Pmode,
+                                                   XEXP (XEXP (addr, 0), 0),
+                                                   GEN_INT (v & -16)));
+             else
+               addr = XEXP (XEXP (addr, 0), 0);
+             p1_lo = GEN_INT (v & 15);
+           }
+       }
+      else if (GET_CODE (addr) == CONST_INT)
+       {
+         p1_lo = GEN_INT (INTVAL (addr) & 15);
+         addr = GEN_INT (INTVAL (addr) & -16);
+       }
+    }
+
+  scalar = store_with_one_insn_p (ops[0]);
+  if (!scalar)
+    {
+      /* We could copy the flags from the ops[0] MEM to mem here,
+         We don't because we want this load to be optimized away if
+         possible, and copying the flags will prevent that in certain
+         cases, e.g. consider the volatile flag. */
+
+      emit_insn (gen_lq (reg, copy_rtx (addr)));
+
+      if (!p0 || reg_align (p0) >= 128)
+       p0 = stack_pointer_rtx;
+      if (!p1_lo)
+       p1_lo = const0_rtx;
+
+      emit_insn (gen_cpat (pat, p0, p1_lo, GEN_INT (GET_MODE_SIZE (mode))));
+      emit_insn (gen_shufb (reg, ops[1], reg, pat));
+    }
+  else if (reload_completed)
+    {
+      if (GET_CODE (ops[1]) == REG)
+       emit_move_insn (reg, gen_rtx_REG (GET_MODE (reg), REGNO (ops[1])));
+      else if (GET_CODE (ops[1]) == SUBREG)
+       emit_move_insn (reg,
+                       gen_rtx_REG (GET_MODE (reg),
+                                    REGNO (SUBREG_REG (ops[1]))));
+      else
+       abort ();
+    }
+  else
+    {
+      if (GET_CODE (ops[1]) == REG)
+       emit_insn (gen_spu_convert (reg, ops[1]));
+      else if (GET_CODE (ops[1]) == SUBREG)
+       emit_insn (gen_spu_convert (reg, SUBREG_REG (ops[1])));
+      else
+       abort ();
+    }
+
+  if (GET_MODE_SIZE (mode) < 4 && scalar)
+    emit_insn (gen_shlqby_ti
+              (reg, reg, GEN_INT (4 - GET_MODE_SIZE (mode))));
+
+  addr = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16));
+  smem = change_address (ops[0], TImode, addr);
+  /* We can't use the previous alias set because the memory has changed
+     size and can potentially overlap objects of other types.  */
+  set_mem_alias_set (smem, 0);
+
+  emit_insn (gen_stq_ti (smem, reg));
+}
+
+/* Return TRUE if X is MEM which is a struct member reference
+   and the member can safely be loaded and stored with a single
+   instruction because it is padded. */
+static int
+mem_is_padded_component_ref (rtx x)
+{
+  tree t = MEM_EXPR (x);
+  tree r;
+  if (!t || TREE_CODE (t) != COMPONENT_REF)
+    return 0;
+  t = TREE_OPERAND (t, 1);
+  if (!t || TREE_CODE (t) != FIELD_DECL
+      || DECL_ALIGN (t) < 128 || AGGREGATE_TYPE_P (TREE_TYPE (t)))
+    return 0;
+  /* Only do this for RECORD_TYPEs, not UNION_TYPEs. */
+  r = DECL_FIELD_CONTEXT (t);
+  if (!r || TREE_CODE (r) != RECORD_TYPE)
+    return 0;
+  /* Make sure they are the same mode */
+  if (GET_MODE (x) != TYPE_MODE (TREE_TYPE (t)))
+    return 0;
+  /* If there are no following fields then the field alignment assures
+     the structure is padded to the alignement which means this field is
+     padded too. */
+  if (TREE_CHAIN (t) == 0)
+    return 1;
+  /* If the following field is also aligned then this field will be
+     padded. */
+  t = TREE_CHAIN (t);
+  if (TREE_CODE (t) == FIELD_DECL && DECL_ALIGN (t) >= 128)
+    return 1;
+  return 0;
+}
+
+int
+spu_valid_move (rtx * ops)
+{
+  enum machine_mode mode = GET_MODE (ops[0]);
+  if (!register_operand (ops[0], mode) && !register_operand (ops[1], mode))
+    return 0;
+
+  /* init_expr_once tries to recog against load and store insns to set
+     the direct_load[] and direct_store[] arrays.  We always want to
+     consider those loads and stores valid.  init_expr_once is called in
+     the context of a dummy function which does not have a decl. */
+  if (cfun->decl == 0)
+    return 1;
+
+  /* Don't allows loads/stores which would require more than 1 insn.
+     During and after reload we assume loads and stores only take 1
+     insn. */
+  if (GET_MODE_SIZE (mode) < 16 && !reload_in_progress && !reload_completed)
+    {
+      if (GET_CODE (ops[0]) == MEM
+         && (GET_MODE_SIZE (mode) < 4
+             || !(store_with_one_insn_p (ops[0])
+                  || mem_is_padded_component_ref (ops[0]))))
+       return 0;
+      if (GET_CODE (ops[1]) == MEM
+         && (GET_MODE_SIZE (mode) < 4 || !aligned_mem_p (ops[1])))
+       return 0;
+    }
+  return 1;
+}
+
+/* Return TRUE if x is a CONST_INT, CONST_DOUBLE or CONST_VECTOR that
+   can be generated using the fsmbi instruction. */
+int
+fsmbi_const_p (rtx x)
+{
+  enum machine_mode mode;
+  unsigned char arr[16];
+  int i;
+
+  /* We can always choose DImode for CONST_INT because the high bits of
+     an SImode will always be all 1s, i.e., valid for fsmbi. */
+  mode = GET_CODE (x) == CONST_INT ? DImode : GET_MODE (x);
+  constant_to_array (mode, x, arr);
+
+  for (i = 0; i < 16; i++)
+    if (arr[i] != 0 && arr[i] != 0xff)
+      return 0;
+  return 1;
+}
+
+/* Convert a CONST_INT, CONST_DOUBLE, or CONST_VECTOR into a 16 byte
+   array.  Use MODE for CONST_INT's.  When the constant's mode is smaller
+   than 16 bytes, the value is repeated across the rest of the array. */
+void
+constant_to_array (enum machine_mode mode, rtx x, unsigned char arr[16])
+{
+  HOST_WIDE_INT val;
+  int i, j, first;
+
+  memset (arr, 0, 16);
+  mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : mode;
+  if (GET_CODE (x) == CONST_INT
+      || (GET_CODE (x) == CONST_DOUBLE
+         && (mode == SFmode || mode == DFmode)))
+    {
+      gcc_assert (mode != VOIDmode && mode != BLKmode);
+
+      if (GET_CODE (x) == CONST_DOUBLE)
+       val = const_double_to_hwint (x);
+      else
+       val = INTVAL (x);
+      first = GET_MODE_SIZE (mode) - 1;
+      for (i = first; i >= 0; i--)
+       {
+         arr[i] = val & 0xff;
+         val >>= 8;
+       }
+      /* Splat the constant across the whole array. */
+      for (j = 0, i = first + 1; i < 16; i++)
+       {
+         arr[i] = arr[j];
+         j = (j == first) ? 0 : j + 1;
+       }
+    }
+  else if (GET_CODE (x) == CONST_DOUBLE)
+    {
+      val = CONST_DOUBLE_LOW (x);
+      for (i = 15; i >= 8; i--)
+       {
+         arr[i] = val & 0xff;
+         val >>= 8;
+       }
+      val = CONST_DOUBLE_HIGH (x);
+      for (i = 7; i >= 0; i--)
+       {
+         arr[i] = val & 0xff;
+         val >>= 8;
+       }
+    }
+  else if (GET_CODE (x) == CONST_VECTOR)
+    {
+      int units;
+      rtx elt;
+      mode = GET_MODE_INNER (mode);
+      units = CONST_VECTOR_NUNITS (x);
+      for (i = 0; i < units; i++)
+       {
+         elt = CONST_VECTOR_ELT (x, i);
+         if (GET_CODE (elt) == CONST_INT || GET_CODE (elt) == CONST_DOUBLE)
+           {
+             if (GET_CODE (elt) == CONST_DOUBLE)
+               val = const_double_to_hwint (elt);
+             else
+               val = INTVAL (elt);
+             first = GET_MODE_SIZE (mode) - 1;
+             if (first + i * GET_MODE_SIZE (mode) > 16)
+               abort ();
+             for (j = first; j >= 0; j--)
+               {
+                 arr[j + i * GET_MODE_SIZE (mode)] = val & 0xff;
+                 val >>= 8;
+               }
+           }
+       }
+    }
+  else
+    gcc_unreachable();
+}
+
+/* Convert a 16 byte array to a constant of mode MODE.  When MODE is
+   smaller than 16 bytes, use the bytes that would represent that value
+   in a register, e.g., for QImode return the value of arr[3].  */
+rtx
+array_to_constant (enum machine_mode mode, unsigned char arr[16])
+{
+  enum machine_mode inner_mode;
+  rtvec v;
+  int units, size, i, j, k;
+  HOST_WIDE_INT val;
+
+  if (GET_MODE_CLASS (mode) == MODE_INT
+      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+    {
+      j = GET_MODE_SIZE (mode);
+      i = j < 4 ? 4 - j : 0;
+      for (val = 0; i < j; i++)
+       val = (val << 8) | arr[i];
+      val = trunc_int_for_mode (val, mode);
+      return GEN_INT (val);
+    }
+
+  if (mode == TImode)
+    {
+      HOST_WIDE_INT high;
+      for (i = high = 0; i < 8; i++)
+       high = (high << 8) | arr[i];
+      for (i = 8, val = 0; i < 16; i++)
+       val = (val << 8) | arr[i];
+      return immed_double_const (val, high, TImode);
+    }
+  if (mode == SFmode)
+    {
+      val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+      val = trunc_int_for_mode (val, SImode);
+      return hwint_to_const_double (val, SFmode);
+    }
+  if (mode == DFmode)
+    {
+      val = (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3];
+      val <<= 32;
+      val |= (arr[4] << 24) | (arr[5] << 16) | (arr[6] << 8) | arr[7];
+      return hwint_to_const_double (val, DFmode);
+    }
+
+  if (!VECTOR_MODE_P (mode))
+    abort ();
+
+  units = GET_MODE_NUNITS (mode);
+  size = GET_MODE_UNIT_SIZE (mode);
+  inner_mode = GET_MODE_INNER (mode);
+  v = rtvec_alloc (units);
+
+  for (k = i = 0; i < units; ++i)
+    {
+      val = 0;
+      for (j = 0; j < size; j++, k++)
+       val = (val << 8) | arr[k];
+
+      if (GET_MODE_CLASS (inner_mode) == MODE_FLOAT)
+       RTVEC_ELT (v, i) = hwint_to_const_double (inner_mode, val);
+      else
+       RTVEC_ELT (v, i) = GEN_INT (trunc_int_for_mode (val, inner_mode));
+    }
+  if (k > 16)
+    abort ();
+
+  return gen_rtx_CONST_VECTOR (mode, v);
+}
+
+static void
+reloc_diagnostic (rtx x)
+{
+  tree loc_decl, decl = 0;
+  const char *msg;
+  if (!flag_pic || !(TARGET_WARN_RELOC || TARGET_ERROR_RELOC))
+    return;
+
+  if (GET_CODE (x) == SYMBOL_REF)
+    decl = SYMBOL_REF_DECL (x);
+  else if (GET_CODE (x) == CONST
+          && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
+    decl = SYMBOL_REF_DECL (XEXP (XEXP (x, 0), 0));
+
+  /* SYMBOL_REF_DECL is not necessarily a DECL. */
+  if (decl && !DECL_P (decl))
+    decl = 0;
+
+  /* We use last_assemble_variable_decl to get line information.  It's
+     not always going to be right and might not even be close, but will
+     be right for the more common cases. */
+  if (!last_assemble_variable_decl)
+    loc_decl = decl;
+  else
+    loc_decl = last_assemble_variable_decl;
+
+  /* The decl could be a string constant.  */
+  if (decl && DECL_P (decl))
+    msg = "%Jcreating run-time relocation for %qD";
+  else
+    msg = "creating run-time relocation";
+
+  if (TARGET_ERROR_RELOC) /** default : error reloc **/
+    error (msg, loc_decl, decl);
+  else
+    warning (0, msg, loc_decl, decl);
+}
+
+/* Hook into assemble_integer so we can generate an error for run-time
+   relocations.  The SPU ABI disallows them. */
+static bool
+spu_assemble_integer (rtx x, unsigned int size, int aligned_p)
+{
+  /* By default run-time relocations aren't supported, but we allow them
+     in case users support it in their own run-time loader.  And we provide
+     a warning for those users that don't.  */
+  if ((GET_CODE (x) == SYMBOL_REF)
+      || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST)
+    reloc_diagnostic (x);
+
+  return default_assemble_integer (x, size, aligned_p);
+}
+
+static void
+spu_asm_globalize_label (FILE * file, const char *name)
+{
+  fputs ("\t.global\t", file);
+  assemble_name (file, name);
+  fputs ("\n", file);
+}
+
+static bool
+spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
+{
+  enum machine_mode mode = GET_MODE (x);
+  int cost = COSTS_N_INSNS (2);
+
+  /* Folding to a CONST_VECTOR will use extra space but there might
+     be only a small savings in cycles.  We'd like to use a CONST_VECTOR
+     only if it allows us to fold away multiple insns.  Changin the cost
+     of a CONST_VECTOR here (or in CONST_COSTS) doesn't help though
+     because this cost will only be compared against a single insn. 
+     if (code == CONST_VECTOR)
+       return (LEGITIMATE_CONSTANT_P(x)) ? cost : COSTS_N_INSNS(6);
+   */
+
+  /* Use defaults for float operations.  Not accurate but good enough. */
+  if (mode == DFmode)
+    {
+      *total = COSTS_N_INSNS (13);
+      return true;
+    }
+  if (mode == SFmode)
+    {
+      *total = COSTS_N_INSNS (6);
+      return true;
+    }
+  switch (code)
+    {
+    case CONST_INT:
+      if (satisfies_constraint_K (x))
+       *total = 0;
+      else if (INTVAL (x) >= -0x80000000ll && INTVAL (x) <= 0xffffffffll)
+       *total = COSTS_N_INSNS (1);
+      else
+       *total = COSTS_N_INSNS (3);
+      return true;
+
+    case CONST:
+      *total = COSTS_N_INSNS (3);
+      return true;
+
+    case LABEL_REF:
+    case SYMBOL_REF:
+      *total = COSTS_N_INSNS (0);
+      return true;
+
+    case CONST_DOUBLE:
+      *total = COSTS_N_INSNS (5);
+      return true;
+
+    case FLOAT_EXTEND:
+    case FLOAT_TRUNCATE:
+    case FLOAT:
+    case UNSIGNED_FLOAT:
+    case FIX:
+    case UNSIGNED_FIX:
+      *total = COSTS_N_INSNS (7);
+      return true;
+
+    case PLUS:
+      if (mode == TImode)
+       {
+         *total = COSTS_N_INSNS (9);
+         return true;
+       }
+      break;
+
+    case MULT:
+      cost =
+       GET_CODE (XEXP (x, 0)) ==
+       REG ? COSTS_N_INSNS (12) : COSTS_N_INSNS (7);
+      if (mode == SImode && GET_CODE (XEXP (x, 0)) == REG)
+       {
+         if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+           {
+             HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+             cost = COSTS_N_INSNS (14);
+             if ((val & 0xffff) == 0)
+               cost = COSTS_N_INSNS (9);
+             else if (val > 0 && val < 0x10000)
+               cost = COSTS_N_INSNS (11);
+           }
+       }
+      *total = cost;
+      return true;
+    case DIV:
+    case UDIV:
+    case MOD:
+    case UMOD:
+      *total = COSTS_N_INSNS (20);
+      return true;
+    case ROTATE:
+    case ROTATERT:
+    case ASHIFT:
+    case ASHIFTRT:
+    case LSHIFTRT:
+      *total = COSTS_N_INSNS (4);
+      return true;
+    case UNSPEC:
+      if (XINT (x, 1) == UNSPEC_CONVERT)
+       *total = COSTS_N_INSNS (0);
+      else
+       *total = COSTS_N_INSNS (4);
+      return true;
+    }
+  /* Scale cost by mode size.  Except when initializing (cfun->decl == 0). */
+  if (GET_MODE_CLASS (mode) == MODE_INT
+      && GET_MODE_SIZE (mode) > GET_MODE_SIZE (SImode) && cfun && cfun->decl)
+    cost = cost * (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode))
+      * (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
+  *total = cost;
+  return true;
+}
+
+enum machine_mode
+spu_eh_return_filter_mode (void)
+{
+  /* We would like this to be SImode, but sjlj exceptions seems to work
+     only with word_mode. */
+  return TImode;
+}
+
+/* Decide whether we can make a sibling call to a function.  DECL is the
+   declaration of the function being targeted by the call and EXP is the
+   CALL_EXPR representing the call.  */
+static bool
+spu_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+{
+  return decl && !TARGET_LARGE_MEM;
+}
+
+/* We need to correctly update the back chain pointer and the Available
+   Stack Size (which is in the second slot of the sp register.) */
+void
+spu_allocate_stack (rtx op0, rtx op1)
+{
+  HOST_WIDE_INT v;
+  rtx chain = gen_reg_rtx (V4SImode);
+  rtx stack_bot = gen_frame_mem (V4SImode, stack_pointer_rtx);
+  rtx sp = gen_reg_rtx (V4SImode);
+  rtx splatted = gen_reg_rtx (V4SImode);
+  rtx pat = gen_reg_rtx (TImode);
+
+  /* copy the back chain so we can save it back again. */
+  emit_move_insn (chain, stack_bot);
+
+  op1 = force_reg (SImode, op1);
+
+  v = 0x1020300010203ll;
+  emit_move_insn (pat, immed_double_const (v, v, TImode));
+  emit_insn (gen_shufb (splatted, op1, op1, pat));
+
+  emit_insn (gen_spu_convert (sp, stack_pointer_rtx));
+  emit_insn (gen_subv4si3 (sp, sp, splatted));
+
+  if (flag_stack_check)
+    {
+      rtx avail = gen_reg_rtx(SImode);
+      rtx result = gen_reg_rtx(SImode);
+      emit_insn (gen_vec_extractv4si (avail, sp, GEN_INT (1)));
+      emit_insn (gen_cgt_si(result, avail, GEN_INT (-1)));
+      emit_insn (gen_spu_heq (result, GEN_INT(0) ));
+    }
+
+  emit_insn (gen_spu_convert (stack_pointer_rtx, sp));
+
+  emit_move_insn (stack_bot, chain);
+
+  emit_move_insn (op0, virtual_stack_dynamic_rtx);
+}
+
+void
+spu_restore_stack_nonlocal (rtx op0 ATTRIBUTE_UNUSED, rtx op1)
+{
+  static unsigned char arr[16] =
+    { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 };
+  rtx temp = gen_reg_rtx (SImode);
+  rtx temp2 = gen_reg_rtx (SImode);
+  rtx temp3 = gen_reg_rtx (V4SImode);
+  rtx temp4 = gen_reg_rtx (V4SImode);
+  rtx pat = gen_reg_rtx (TImode);
+  rtx sp = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM);
+
+  /* Restore the backchain from the first word, sp from the second.  */
+  emit_move_insn (temp2, adjust_address_nv (op1, SImode, 0));
+  emit_move_insn (temp, adjust_address_nv (op1, SImode, 4));
+
+  emit_move_insn (pat, array_to_constant (TImode, arr));
+
+  /* Compute Available Stack Size for sp */
+  emit_insn (gen_subsi3 (temp, temp, stack_pointer_rtx));
+  emit_insn (gen_shufb (temp3, temp, temp, pat));
+
+  /* Compute Available Stack Size for back chain */
+  emit_insn (gen_subsi3 (temp2, temp2, stack_pointer_rtx));
+  emit_insn (gen_shufb (temp4, temp2, temp2, pat));
+  emit_insn (gen_addv4si3 (temp4, sp, temp4));
+
+  emit_insn (gen_addv4si3 (sp, sp, temp3));
+  emit_move_insn (gen_frame_mem (V4SImode, stack_pointer_rtx), temp4);
+}
+
+static void
+spu_init_libfuncs (void)
+{
+  set_optab_libfunc (smul_optab, DImode, "__muldi3");
+  set_optab_libfunc (sdiv_optab, DImode, "__divdi3");
+  set_optab_libfunc (smod_optab, DImode, "__moddi3");
+  set_optab_libfunc (udiv_optab, DImode, "__udivdi3");
+  set_optab_libfunc (umod_optab, DImode, "__umoddi3");
+  set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
+  set_optab_libfunc (ffs_optab, DImode, "__ffsdi2");
+  set_optab_libfunc (clz_optab, DImode, "__clzdi2");
+  set_optab_libfunc (ctz_optab, DImode, "__ctzdi2");
+  set_optab_libfunc (popcount_optab, DImode, "__popcountdi2");
+  set_optab_libfunc (parity_optab, DImode, "__paritydi2");
+
+  set_conv_libfunc (ufloat_optab, DFmode, SImode, "__float_unssidf");
+  set_conv_libfunc (ufloat_optab, DFmode, DImode, "__float_unsdidf");
+}
+
+/* Make a subreg, stripping any existing subreg.  We could possibly just
+   call simplify_subreg, but in this case we know what we want. */
+rtx
+spu_gen_subreg (enum machine_mode mode, rtx x)
+{
+  if (GET_CODE (x) == SUBREG)
+    x = SUBREG_REG (x);
+  if (GET_MODE (x) == mode)
+    return x;
+  return gen_rtx_SUBREG (mode, x, 0);
+}
+
+static bool
+spu_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+{
+  return (TYPE_MODE (type) == BLKmode
+         && ((type) == 0
+             || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
+             || int_size_in_bytes (type) >
+             (MAX_REGISTER_RETURN * UNITS_PER_WORD)));
+}
+\f
+/* Create the built-in types and functions */
+
+struct spu_builtin_description spu_builtins[] = {
+#define DEF_BUILTIN(fcode, icode, name, type, params) \
+  {fcode, icode, name, type, params, NULL_TREE},
+#include "spu-builtins.def"
+#undef DEF_BUILTIN
+};
+
+static void
+spu_init_builtins (void)
+{
+  struct spu_builtin_description *d;
+  unsigned int i;
+
+  V16QI_type_node = build_vector_type (intQI_type_node, 16);
+  V8HI_type_node = build_vector_type (intHI_type_node, 8);
+  V4SI_type_node = build_vector_type (intSI_type_node, 4);
+  V2DI_type_node = build_vector_type (intDI_type_node, 2);
+  V4SF_type_node = build_vector_type (float_type_node, 4);
+  V2DF_type_node = build_vector_type (double_type_node, 2);
+
+  unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
+  unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
+  unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
+  unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
+
+  spu_builtin_types[SPU_BTI_QUADWORD] = V16QI_type_node;
+
+  spu_builtin_types[SPU_BTI_7] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_S7] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_U7] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_S10] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_S10_4] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_U14] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_16] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_S16] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_S16_2] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_U16] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_U16_2] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_U18] = global_trees[TI_INTSI_TYPE];
+
+  spu_builtin_types[SPU_BTI_INTQI] = global_trees[TI_INTQI_TYPE];
+  spu_builtin_types[SPU_BTI_INTHI] = global_trees[TI_INTHI_TYPE];
+  spu_builtin_types[SPU_BTI_INTSI] = global_trees[TI_INTSI_TYPE];
+  spu_builtin_types[SPU_BTI_INTDI] = global_trees[TI_INTDI_TYPE];
+  spu_builtin_types[SPU_BTI_UINTQI] = global_trees[TI_UINTQI_TYPE];
+  spu_builtin_types[SPU_BTI_UINTHI] = global_trees[TI_UINTHI_TYPE];
+  spu_builtin_types[SPU_BTI_UINTSI] = global_trees[TI_UINTSI_TYPE];
+  spu_builtin_types[SPU_BTI_UINTDI] = global_trees[TI_UINTDI_TYPE];
+
+  spu_builtin_types[SPU_BTI_FLOAT] = global_trees[TI_FLOAT_TYPE];
+  spu_builtin_types[SPU_BTI_DOUBLE] = global_trees[TI_DOUBLE_TYPE];
+
+  spu_builtin_types[SPU_BTI_VOID] = global_trees[TI_VOID_TYPE];
+
+  spu_builtin_types[SPU_BTI_PTR] =
+    build_pointer_type (build_qualified_type
+                       (void_type_node,
+                        TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE));
+
+  /* For each builtin we build a new prototype.  The tree code will make
+     sure nodes are shared. */
+  for (i = 0, d = spu_builtins; i < NUM_SPU_BUILTINS; i++, d++)
+    {
+      tree p;
+      char name[64];           /* build_function will make a copy. */
+      int parm;
+
+      if (d->name == 0)
+       continue;
+
+      /* find last parm */
+      for (parm = 1; d->parm[parm] != SPU_BTI_END_OF_PARAMS; parm++)
+       {
+       }
+
+      p = void_list_node;
+      while (parm > 1)
+       p = tree_cons (NULL_TREE, spu_builtin_types[d->parm[--parm]], p);
+
+      p = build_function_type (spu_builtin_types[d->parm[0]], p);
+
+      sprintf (name, "__builtin_%s", d->name);
+      d->fndecl =
+       add_builtin_function (name, p, END_BUILTINS + i, BUILT_IN_MD,
+                             NULL, NULL_TREE);
+    }
+}
+
+int
+spu_safe_dma (HOST_WIDE_INT channel)
+{
+  return (channel >= 21 && channel <= 27);
+}
+
+void
+spu_builtin_splats (rtx ops[])
+{
+  enum machine_mode mode = GET_MODE (ops[0]);
+  if (GET_CODE (ops[1]) == CONST_INT || GET_CODE (ops[1]) == CONST_DOUBLE)
+    {
+      unsigned char arr[16];
+      constant_to_array (GET_MODE_INNER (mode), ops[1], arr);
+      emit_move_insn (ops[0], array_to_constant (mode, arr));
+    }
+  else if (GET_MODE (ops[0]) == V4SImode && CONSTANT_P (ops[1]))
+    {
+      rtvec v = rtvec_alloc (4);
+      RTVEC_ELT (v, 0) = ops[1];
+      RTVEC_ELT (v, 1) = ops[1];
+      RTVEC_ELT (v, 2) = ops[1];
+      RTVEC_ELT (v, 3) = ops[1];
+      emit_move_insn (ops[0], gen_rtx_CONST_VECTOR (mode, v));
+    }
+  else
+    {
+      rtx reg = gen_reg_rtx (TImode);
+      rtx shuf;
+      if (GET_CODE (ops[1]) != REG
+         && GET_CODE (ops[1]) != SUBREG)
+       ops[1] = force_reg (GET_MODE_INNER (mode), ops[1]);
+      switch (mode)
+       {
+       case V2DImode:
+       case V2DFmode:
+         shuf =
+           immed_double_const (0x0001020304050607ll, 0x1011121314151617ll,
+                               TImode);
+         break;
+       case V4SImode:
+       case V4SFmode:
+         shuf =
+           immed_double_const (0x0001020300010203ll, 0x0001020300010203ll,
+                               TImode);
+         break;
+       case V8HImode:
+         shuf =
+           immed_double_const (0x0203020302030203ll, 0x0203020302030203ll,
+                               TImode);
+         break;
+       case V16QImode:
+         shuf =
+           immed_double_const (0x0303030303030303ll, 0x0303030303030303ll,
+                               TImode);
+         break;
+       default:
+         abort ();
+       }
+      emit_move_insn (reg, shuf);
+      emit_insn (gen_shufb (ops[0], ops[1], ops[1], reg));
+    }
+}
+
+void
+spu_builtin_extract (rtx ops[])
+{
+  enum machine_mode mode;
+  rtx rot, from, tmp;
+
+  mode = GET_MODE (ops[1]);
+
+  if (GET_CODE (ops[2]) == CONST_INT)
+    {
+      switch (mode)
+       {
+       case V16QImode:
+         emit_insn (gen_vec_extractv16qi (ops[0], ops[1], ops[2]));
+         break;
+       case V8HImode:
+         emit_insn (gen_vec_extractv8hi (ops[0], ops[1], ops[2]));
+         break;
+       case V4SFmode:
+         emit_insn (gen_vec_extractv4sf (ops[0], ops[1], ops[2]));
+         break;
+       case V4SImode:
+         emit_insn (gen_vec_extractv4si (ops[0], ops[1], ops[2]));
+         break;
+       case V2DImode:
+         emit_insn (gen_vec_extractv2di (ops[0], ops[1], ops[2]));
+         break;
+       case V2DFmode:
+         emit_insn (gen_vec_extractv2df (ops[0], ops[1], ops[2]));
+         break;
+       default:
+         abort ();
+       }
+      return;
+    }
+
+  from = spu_gen_subreg (TImode, ops[1]);
+  rot = gen_reg_rtx (TImode);
+  tmp = gen_reg_rtx (SImode);
+
+  switch (mode)
+    {
+    case V16QImode:
+      emit_insn (gen_addsi3 (tmp, ops[2], GEN_INT (-3)));
+      break;
+    case V8HImode:
+      emit_insn (gen_addsi3 (tmp, ops[2], ops[2]));
+      emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (-2)));
+      break;
+    case V4SFmode:
+    case V4SImode:
+      emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (2)));
+      break;
+    case V2DImode:
+    case V2DFmode:
+      emit_insn (gen_ashlsi3 (tmp, ops[2], GEN_INT (3)));
+      break;
+    default:
+      abort ();
+    }
+  emit_insn (gen_rotqby_ti (rot, from, tmp));
+
+  emit_insn (gen_spu_convert (ops[0], rot));
+}
+
+void
+spu_builtin_insert (rtx ops[])
+{
+  enum machine_mode mode = GET_MODE (ops[0]);
+  enum machine_mode imode = GET_MODE_INNER (mode);
+  rtx mask = gen_reg_rtx (TImode);
+  rtx offset;
+
+  if (GET_CODE (ops[3]) == CONST_INT)
+    offset = GEN_INT (INTVAL (ops[3]) * GET_MODE_SIZE (imode));
+  else
+    {
+      offset = gen_reg_rtx (SImode);
+      emit_insn (gen_mulsi3
+                (offset, ops[3], GEN_INT (GET_MODE_SIZE (imode))));
+    }
+  emit_insn (gen_cpat
+            (mask, stack_pointer_rtx, offset,
+             GEN_INT (GET_MODE_SIZE (imode))));
+  emit_insn (gen_shufb (ops[0], ops[1], ops[2], mask));
+}
+
+void
+spu_builtin_promote (rtx ops[])
+{
+  enum machine_mode mode, imode;
+  rtx rot, from, offset;
+  HOST_WIDE_INT pos;
+
+  mode = GET_MODE (ops[0]);
+  imode = GET_MODE_INNER (mode);
+
+  from = gen_reg_rtx (TImode);
+  rot = spu_gen_subreg (TImode, ops[0]);
+
+  emit_insn (gen_spu_convert (from, ops[1]));
+
+  if (GET_CODE (ops[2]) == CONST_INT)
+    {
+      pos = -GET_MODE_SIZE (imode) * INTVAL (ops[2]);
+      if (GET_MODE_SIZE (imode) < 4)
+       pos += 4 - GET_MODE_SIZE (imode);
+      offset = GEN_INT (pos & 15);
+    }
+  else
+    {
+      offset = gen_reg_rtx (SImode);
+      switch (mode)
+       {
+       case V16QImode:
+         emit_insn (gen_subsi3 (offset, GEN_INT (3), ops[2]));
+         break;
+       case V8HImode:
+         emit_insn (gen_subsi3 (offset, GEN_INT (1), ops[2]));
+         emit_insn (gen_addsi3 (offset, offset, offset));
+         break;
+       case V4SFmode:
+       case V4SImode:
+         emit_insn (gen_subsi3 (offset, GEN_INT (0), ops[2]));
+         emit_insn (gen_ashlsi3 (offset, offset, GEN_INT (2)));
+         break;
+       case V2DImode:
+       case V2DFmode:
+         emit_insn (gen_ashlsi3 (offset, ops[2], GEN_INT (3)));
+         break;
+       default:
+         abort ();
+       }
+    }
+  emit_insn (gen_rotqby_ti (rot, from, offset));
+}
+
+void
+spu_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
+{
+  rtx shuf = gen_reg_rtx (V4SImode);
+  rtx insn = gen_reg_rtx (V4SImode);
+  rtx shufc;
+  rtx insnc;
+  rtx mem;
+
+  fnaddr = force_reg (SImode, fnaddr);
+  cxt = force_reg (SImode, cxt);
+
+  if (TARGET_LARGE_MEM)
+    {
+      rtx rotl = gen_reg_rtx (V4SImode);
+      rtx mask = gen_reg_rtx (V4SImode);
+      rtx bi = gen_reg_rtx (SImode);
+      unsigned char shufa[16] = {
+       2, 3, 0, 1, 18, 19, 16, 17,
+       0, 1, 2, 3, 16, 17, 18, 19
+      };
+      unsigned char insna[16] = {
+       0x41, 0, 0, 79,
+       0x41, 0, 0, STATIC_CHAIN_REGNUM,
+       0x60, 0x80, 0, 79,
+       0x60, 0x80, 0, STATIC_CHAIN_REGNUM
+      };
+
+      shufc = force_reg (TImode, array_to_constant (TImode, shufa));
+      insnc = force_reg (V4SImode, array_to_constant (V4SImode, insna));
+
+      emit_insn (gen_shufb (shuf, fnaddr, cxt, shufc));
+      emit_insn (gen_rotlv4si3 (rotl, shuf, spu_const (V4SImode, 7)));
+      emit_insn (gen_movv4si (mask, spu_const (V4SImode, 0xffff << 7)));
+      emit_insn (gen_selb (insn, insnc, rotl, mask));
+
+      mem = memory_address (Pmode, tramp);
+      emit_move_insn (gen_rtx_MEM (V4SImode, mem), insn);
+
+      emit_move_insn (bi, GEN_INT (0x35000000 + (79 << 7)));
+      mem = memory_address (Pmode, plus_constant (tramp, 16));
+      emit_move_insn (gen_rtx_MEM (Pmode, mem), bi);
+    }
+  else
+    {
+      rtx scxt = gen_reg_rtx (SImode);
+      rtx sfnaddr = gen_reg_rtx (SImode);
+      unsigned char insna[16] = {
+       0x42, 0, 0, STATIC_CHAIN_REGNUM,
+       0x30, 0, 0, 0,
+       0, 0, 0, 0,
+       0, 0, 0, 0
+      };
+
+      shufc = gen_reg_rtx (TImode);
+      insnc = force_reg (V4SImode, array_to_constant (V4SImode, insna));
+
+      /* By or'ing all of cxt with the ila opcode we are assuming cxt
+        fits 18 bits and the last 4 are zeros.  This will be true if
+        the stack pointer is initialized to 0x3fff0 at program start,
+        otherwise the ila instruction will be garbage. */
+
+      emit_insn (gen_ashlsi3 (scxt, cxt, GEN_INT (7)));
+      emit_insn (gen_ashlsi3 (sfnaddr, fnaddr, GEN_INT (5)));
+      emit_insn (gen_cpat
+                (shufc, stack_pointer_rtx, GEN_INT (4), GEN_INT (4)));
+      emit_insn (gen_shufb (shuf, sfnaddr, scxt, shufc));
+      emit_insn (gen_iorv4si3 (insn, insnc, shuf));
+
+      mem = memory_address (Pmode, tramp);
+      emit_move_insn (gen_rtx_MEM (V4SImode, mem), insn);
+
+    }
+  emit_insn (gen_sync ());
+}
+
+void
+spu_expand_sign_extend (rtx ops[])
+{
+  unsigned char arr[16];
+  rtx pat = gen_reg_rtx (TImode);
+  rtx sign, c;
+  int i, last;
+  last = GET_MODE (ops[0]) == DImode ? 7 : 15;
+  if (GET_MODE (ops[1]) == QImode)
+    {
+      sign = gen_reg_rtx (HImode);
+      emit_insn (gen_extendqihi2 (sign, ops[1]));
+      for (i = 0; i < 16; i++)
+       arr[i] = 0x12;
+      arr[last] = 0x13;
+    }
+  else
+    {
+      for (i = 0; i < 16; i++)
+       arr[i] = 0x10;
+      switch (GET_MODE (ops[1]))
+       {
+       case HImode:
+         sign = gen_reg_rtx (SImode);
+         emit_insn (gen_extendhisi2 (sign, ops[1]));
+         arr[last] = 0x03;
+         arr[last - 1] = 0x02;
+         break;
+       case SImode:
+         sign = gen_reg_rtx (SImode);
+         emit_insn (gen_ashrsi3 (sign, ops[1], GEN_INT (31)));
+         for (i = 0; i < 4; i++)
+           arr[last - i] = 3 - i;
+         break;
+       case DImode:
+         sign = gen_reg_rtx (SImode);
+         c = gen_reg_rtx (SImode);
+         emit_insn (gen_spu_convert (c, ops[1]));
+         emit_insn (gen_ashrsi3 (sign, c, GEN_INT (31)));
+         for (i = 0; i < 8; i++)
+           arr[last - i] = 7 - i;
+         break;
+       default:
+         abort ();
+       }
+    }
+  emit_move_insn (pat, array_to_constant (TImode, arr));
+  emit_insn (gen_shufb (ops[0], ops[1], sign, pat));
+}
+
+/* expand vector initialization. If there are any constant parts,
+   load constant parts first. Then load any non-constant parts.  */
+void
+spu_expand_vector_init (rtx target, rtx vals)
+{
+  enum machine_mode mode = GET_MODE (target);
+  int n_elts = GET_MODE_NUNITS (mode);
+  int n_var = 0;
+  bool all_same = true;
+  rtx first, x, first_constant = NULL_RTX;
+  int i;
+
+  first = XVECEXP (vals, 0, 0); 
+  for (i = 0; i < n_elts; ++i)
+    {
+      x = XVECEXP (vals, 0, i);
+      if (!CONSTANT_P (x))
+       ++n_var;
+      else
+       {
+         if (first_constant == NULL_RTX)
+           first_constant = x;
+       }
+      if (i > 0 && !rtx_equal_p (x, first))
+       all_same = false;
+    }
+
+  /* if all elements are the same, use splats to repeat elements */
+  if (all_same)
+    {
+      if (!CONSTANT_P (first)
+         && !register_operand (first, GET_MODE (x)))
+       first = force_reg (GET_MODE (first), first);
+      emit_insn (gen_spu_splats (target, first));
+      return;
+    }
+
+  /* load constant parts */
+  if (n_var != n_elts)
+    {
+      if (n_var == 0)
+       {
+         emit_move_insn (target,
+                         gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
+       }
+      else
+       {
+         rtx constant_parts_rtx = copy_rtx (vals);
+
+         gcc_assert (first_constant != NULL_RTX);
+         /* fill empty slots with the first constant, this increases
+            our chance of using splats in the recursive call below. */
+         for (i = 0; i < n_elts; ++i)
+           if (!CONSTANT_P (XVECEXP (constant_parts_rtx, 0, i)))
+             XVECEXP (constant_parts_rtx, 0, i) = first_constant;
+
+         spu_expand_vector_init (target, constant_parts_rtx);
+       }
+    }
+
+  /* load variable parts */
+  if (n_var != 0)
+    {
+      rtx insert_operands[4];
+
+      insert_operands[0] = target;
+      insert_operands[2] = target;
+      for (i = 0; i < n_elts; ++i)
+       {
+         x = XVECEXP (vals, 0, i);
+         if (!CONSTANT_P (x))
+           {
+             if (!register_operand (x, GET_MODE (x)))
+               x = force_reg (GET_MODE (x), x);
+             insert_operands[1] = x;
+             insert_operands[3] = GEN_INT (i);
+             spu_builtin_insert (insert_operands);
+           }
+       }
+    }
+}
diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h
new file mode 100644 (file)
index 0000000..a9714cb
--- /dev/null
@@ -0,0 +1,550 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+\f
+/* Run-time Target */
+#define TARGET_CPU_CPP_BUILTINS()      spu_cpu_cpp_builtins(pfile)
+
+#define TARGET_VERSION fprintf (stderr, " (spu %s)", __DATE__);
+
+#define OVERRIDE_OPTIONS spu_override_options()
+
+extern int target_flags;
+
+/* Default target_flags if no switches specified.  */
+#ifndef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_ERROR_RELOC | MASK_SAFE_DMA | MASK_BRANCH_HINTS)
+#endif
+
+\f
+/* Storage Layout */
+
+#define BITS_BIG_ENDIAN 1
+
+#define BYTES_BIG_ENDIAN 1
+
+#define WORDS_BIG_ENDIAN 1
+
+#define BITS_PER_UNIT 8
+
+/* GCC uses word_mode in many places, assuming that it is the fastest
+   integer mode.  That is not the case for SPU though.  We can't use
+   32 here because (of some reason I can't remember.) */
+#define BITS_PER_WORD 128
+
+#define UNITS_PER_WORD (BITS_PER_WORD/BITS_PER_UNIT)
+
+/* We never actually change UNITS_PER_WORD, but defining this causes
+   libgcc to use some different sizes of types when compiling. */
+#define MIN_UNITS_PER_WORD 4
+
+#define POINTER_SIZE 32
+
+#define PARM_BOUNDARY 128
+
+#define STACK_BOUNDARY 128
+
+/* We want it 8-byte aligned so we can properly use dual-issue
+   instructions, which can only happen on an 8-byte aligned address. */
+#define FUNCTION_BOUNDARY 64
+
+/* We would like to allow a larger alignment for data objects (for DMA)
+   but the aligned attribute is limited by BIGGEST_ALIGNMENT.  We don't
+   define BIGGEST_ALIGNMENT as larger because it is used in other places
+   and would end up wasting space.  (Is this still true?)  */
+#define BIGGEST_ALIGNMENT 128
+
+#define MINIMUM_ATOMIC_ALIGNMENT 128
+
+/* Make all static objects 16-byte aligned.  This allows us to assume
+   they are also padded to 16-bytes, which means we can use a single
+   load or store instruction to access them.  Do the same for objects
+   on the stack.  (Except a bug (?) allows some stack objects to be
+   unaligned.)  */
+#define DATA_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
+#define CONSTANT_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
+#define LOCAL_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128)
+
+#define EMPTY_FIELD_BOUNDARY 32
+
+#define STRICT_ALIGNMENT 1
+
+/* symbol_ref's of functions are not aligned to 16 byte boundary. */
+#define ALIGNED_SYMBOL_REF_P(X) \
+       (GET_CODE (X) == SYMBOL_REF \
+         && (! SYMBOL_REF_FUNCTION_P (X) \
+             || align_functions >= 16))
+
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+#define MAX_FIXED_MODE_SIZE 128
+
+#define STACK_SAVEAREA_MODE(save_level) SImode
+
+#define STACK_SIZE_MODE SImode
+
+/* #define TARGET_FLOAT_FORMAT         SPU_FLOAT_FORMAT */
+
+#ifndef MODE_HAS_NANS
+#define MODE_HAS_NANS(MODE)                                     \
+  (FLOAT_MODE_P (MODE)                                                 \
+   && MODE != SFmode                                           \
+   && !LARGEST_EXPONENT_IS_NORMAL (GET_MODE_BITSIZE (MODE)))
+#endif
+                                                                              
+#ifndef MODE_HAS_INFINITIES
+#define MODE_HAS_INFINITIES(MODE)                               \
+  (FLOAT_MODE_P (MODE)                                                 \
+   && MODE != SFmode                                            \
+   && !LARGEST_EXPONENT_IS_NORMAL (GET_MODE_BITSIZE (MODE)))
+#endif
+                                                                              
+#ifndef MODE_HAS_SIGN_DEPENDENT_ROUNDING
+#define MODE_HAS_SIGN_DEPENDENT_ROUNDING(MODE)                  \
+  (FLOAT_MODE_P (MODE)                                          \
+    && MODE != SFmode                                           \
+   && !ROUND_TOWARDS_ZERO)
+#endif
+
+#define ROUND_TOWARDS_ZERO 1
+
+/* This is certainly true.  Should it be defined?  (It wasn't before.) */
+/* #define LARGEST_EXPONENT_IS_NORMAL(size) (size != 32) */
+
+\f
+/* Type Layout */
+
+#define INT_TYPE_SIZE 32
+
+#define LONG_TYPE_SIZE 32
+
+#define LONG_LONG_TYPE_SIZE 64
+
+#define FLOAT_TYPE_SIZE 32
+
+#define DOUBLE_TYPE_SIZE 64
+
+#define LONG_DOUBLE_TYPE_SIZE 64
+
+#define DEFAULT_SIGNED_CHAR 0
+
+\f
+/* Register Basics */
+
+/* 128-130 are special registers that never appear in assembly code. */
+#define FIRST_PSEUDO_REGISTER 132
+
+#define FIXED_REGISTERS {                          \
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    1, 1, 1, 1 \
+}
+
+#define CALL_USED_REGISTERS {                      \
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+    1, 1, 1, 1 \
+}
+
+#define CONDITIONAL_REGISTER_USAGE \
+       spu_conditional_register_usage()
+
+\f
+/* Values in Registers */
+
+#define HARD_REGNO_NREGS(REGNO, MODE)   \
+    ((GET_MODE_BITSIZE(MODE)+MAX_FIXED_MODE_SIZE-1)/MAX_FIXED_MODE_SIZE)
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+  (GET_MODE_BITSIZE (MODE1) <= MAX_FIXED_MODE_SIZE \
+   && GET_MODE_BITSIZE (MODE2) <= MAX_FIXED_MODE_SIZE)
+
+\f
+/* Register Classes */
+
+enum reg_class { 
+   NO_REGS, 
+   GENERAL_REGS,
+   ALL_REGS,
+   LIM_REG_CLASSES 
+};
+
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+#define REG_CLASS_NAMES \
+{  "NO_REGS", \
+   "GENERAL_REGS", \
+   "ALL_REGS" \
+}
+
+#define REG_CLASS_CONTENTS { \
+    {0, 0, 0, 0, 0}, /* no regs */ \
+    {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3}, /* general regs */ \
+    {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3}} /* all regs */
+
+#define REGNO_REG_CLASS(REGNO) (GENERAL_REGS)
+
+#define BASE_REG_CLASS GENERAL_REGS
+
+#define INDEX_REG_CLASS GENERAL_REGS
+
+#define REGNO_OK_FOR_BASE_P(regno) \
+   ((regno) < FIRST_PSEUDO_REGISTER || (regno > LAST_VIRTUAL_REGISTER && reg_renumber[regno] >= 0))
+
+#define REGNO_OK_FOR_INDEX_P(regno)  \
+   ((regno) < FIRST_PSEUDO_REGISTER || (regno > LAST_VIRTUAL_REGISTER && reg_renumber[regno] >= 0))
+
+#define INT_REG_OK_FOR_INDEX_P(X,STRICT) \
+       ((!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X))))
+#define INT_REG_OK_FOR_BASE_P(X,STRICT) \
+       ((!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X))))
+
+#define PREFERRED_RELOAD_CLASS(X,CLASS)  (CLASS)
+
+#define CLASS_MAX_NREGS(CLASS, MODE)   \
+       ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* GCC assumes that modes are in the lowpart of a register, which is
+   only true for SPU. */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+        ((GET_MODE_SIZE (FROM) > 4 || GET_MODE_SIZE (TO) > 4) \
+        && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
+
+\f
+/* Frame Layout */
+
+#define STACK_GROWS_DOWNWARD
+
+#define STARTING_FRAME_OFFSET (0)
+
+#define STACK_POINTER_OFFSET 32
+
+#define FIRST_PARM_OFFSET(FNDECL) (0)
+
+#define DYNAMIC_CHAIN_ADDRESS(FP) plus_constant ((FP), -16)
+
+#define RETURN_ADDR_RTX(COUNT,FP) (spu_return_addr (COUNT, FP))
+
+/* Should this be defined?  Would it simplify our implementation. */
+/* #define RETURN_ADDR_IN_PREVIOUS_FRAME */
+
+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG(Pmode, LINK_REGISTER_REGNUM)
+
+\f
+/* Stack Checking */
+
+/* We store the Available Stack Size in the second slot of the stack
+   register.   We emit stack checking code during the prologue.  */
+#define STACK_CHECK_BUILTIN 1
+
+\f
+/* Frame Registers, and other registers */
+
+#define STACK_POINTER_REGNUM 1
+
+/* Will be eliminated. */
+#define FRAME_POINTER_REGNUM 128
+
+/* This is not specified in any ABI, so could be set to anything. */
+#define HARD_FRAME_POINTER_REGNUM 127
+
+/* Will be eliminated. */
+#define ARG_POINTER_REGNUM 129
+
+#define STATIC_CHAIN_REGNUM 2
+
+#define LINK_REGISTER_REGNUM 0
+
+/* Used to keep track of instructions that have clobbered the hint
+ * buffer.  Users can also specify it in inline asm. */
+#define HBR_REGNUM 130
+
+/* Used to keep track of enabling and disabling interrupts. */
+#define INTR_REGNUM 131
+
+#define MAX_REGISTER_ARGS    72
+#define FIRST_ARG_REGNUM     3
+#define LAST_ARG_REGNUM      (FIRST_ARG_REGNUM + MAX_REGISTER_ARGS - 1)
+
+#define MAX_REGISTER_RETURN  72
+#define FIRST_RETURN_REGNUM  3
+#define LAST_RETURN_REGNUM   (FIRST_RETURN_REGNUM + MAX_REGISTER_RETURN - 1)
+
+\f
+/* Elimination */
+
+#define FRAME_POINTER_REQUIRED 0
+
+#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) ((DEPTH) = 0)
+
+#define ELIMINABLE_REGS  \
+  {{ARG_POINTER_REGNUM,         STACK_POINTER_REGNUM},                         \
+  {ARG_POINTER_REGNUM,  HARD_FRAME_POINTER_REGNUM},                    \
+  {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                                \
+  {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+
+#define CAN_ELIMINATE(FROM,TO) 1 
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  ((OFFSET) = spu_initial_elimination_offset((FROM),(TO)))
+
+\f
+/* Stack Arguments */
+
+#define ACCUMULATE_OUTGOING_ARGS 1
+
+#define REG_PARM_STACK_SPACE(FNDECL) 0
+
+#define OUTGOING_REG_PARM_STACK_SPACE 
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) (0)
+
+\f
+/* Register Arguments */
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+        (spu_function_arg((CUM),(MODE),(TYPE),(NAMED)))
+
+#define CUMULATIVE_ARGS int
+
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
+               ((CUM) = 0)
+
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
+        ((CUM) += \
+        (TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST ? 1 \
+        : (MODE) == BLKmode ? ((int_size_in_bytes(TYPE)+15) / 16) \
+         : (MODE) == VOIDmode ? 1 \
+        : HARD_REGNO_NREGS(CUM,MODE))
+
+#define FUNCTION_ARG_PADDING(MODE,TYPE) upward
+
+#define PAD_VARARGS_DOWN 0
+
+#define FUNCTION_ARG_REGNO_P(N) ((N) >= (FIRST_ARG_REGNUM) && (N) <= (LAST_ARG_REGNUM))
+
+/* Undocumented */
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+  spu_va_start (valist, nextarg)
+
+\f
+/* Scalar Return */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+        (spu_function_value((VALTYPE),(FUNC)))
+
+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_RETURN_REGNUM)
+
+#define FUNCTION_VALUE_REGNO_P(N) ((N) >= (FIRST_RETURN_REGNUM) && (N) <= (LAST_RETURN_REGNUM))
+
+\f
+/* Aggregate Return */
+
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+\f
+/* Function Entry */
+
+#define EXIT_IGNORE_STACK 0
+
+#define EPILOGUE_USES(REGNO) ((REGNO)==1 ? 1 : 0)
+
+\f
+/* Profiling */
+
+/* Nothing, for now. */
+#define FUNCTION_PROFILER(FILE, LABELNO)  \
+   fprintf (FILE, "\t\n")
+
+\f
+/* Trampolines */
+
+#define TRAMPOLINE_SIZE (TARGET_LARGE_MEM ? 20 : 16)
+
+#define TRAMPOLINE_ALIGNMENT 128
+
+#define INITIALIZE_TRAMPOLINE(TRAMP,FNADDR,CXT) \
+         spu_initialize_trampoline(TRAMP,FNADDR,CXT)
+
+\f
+/* Addressing Modes */
+
+#define CONSTANT_ADDRESS_P(X)   spu_constant_address_p(X)
+
+#define MAX_REGS_PER_ADDRESS 2
+
+#ifdef REG_OK_STRICT
+# define REG_OK_STRICT_FLAG 1
+#else
+# define REG_OK_STRICT_FLAG 0
+#endif
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                        \
+    { if (spu_legitimate_address (MODE, X, REG_OK_STRICT_FLAG))        \
+       goto ADDR;                                              \
+    }
+
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
+  {  rtx result = spu_legitimize_address (X, OLDX, MODE);      \
+     if (result != NULL_RTX)                                   \
+       {                                                       \
+        (X) = result;                                          \
+        goto WIN;                                              \
+       }                                                       \
+  }
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
+
+#define LEGITIMATE_CONSTANT_P(X) spu_legitimate_constant_p(X)
+
+\f
+/* Costs */
+
+#define BRANCH_COST spu_branch_cost
+
+#define SLOW_BYTE_ACCESS 0
+
+#define MOVE_RATIO 32
+
+#define NO_FUNCTION_CSE
+
+\f
+/* Sections */
+
+#define TEXT_SECTION_ASM_OP ".text"
+
+#define DATA_SECTION_ASM_OP ".data"
+
+#define JUMP_TABLES_IN_TEXT_SECTION 1
+
+\f
+/* PIC */
+#define PIC_OFFSET_TABLE_REGNUM 126
+
+\f
+/* File Framework */
+
+#define ASM_APP_ON ""
+
+#define ASM_APP_OFF ""
+
+#define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \
+  do { fprintf (STREAM, "\t.file\t");                  \
+       output_quoted_string (STREAM, NAME);            \
+       fprintf (STREAM, "\n");                         \
+  } while (0)
+
+\f
+/* Uninitialized Data */
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
+( fputs (".comm ", (FILE)),                    \
+  assemble_name ((FILE), (NAME)),              \
+  fprintf ((FILE), ",%d\n", (ROUNDED)))
+
+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
+( fputs (".lcomm ", (FILE)),                   \
+  assemble_name ((FILE), (NAME)),              \
+  fprintf ((FILE), ",%d\n", (ROUNDED)))
+
+\f
+/* Label Output */
+#define ASM_OUTPUT_LABEL(FILE,NAME)    \
+  do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
+
+#define ASM_OUTPUT_LABELREF(FILE, NAME) \
+  asm_fprintf (FILE, "%U%s", default_strip_name_encoding (NAME))
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),   \
+  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+
+\f
+/* Instruction Output */
+#define REGISTER_NAMES \
+{"$lr", "$sp", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", \
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", \
+ "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", \
+ "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", \
+ "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", \
+ "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", \
+ "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", \
+ "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", \
+ "$vfp", "$vap", "hbr", "intr" \
+}
+
+#define PRINT_OPERAND(FILE, X, CODE)  print_operand(FILE, X, CODE)
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
+ print_operand_address (FILE, ADDR)
+
+#define LOCAL_LABEL_PREFIX "."
+
+#define USER_LABEL_PREFIX ""
+
+\f
+/* Dispatch Tables */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)  \
+  fprintf (FILE, "\t.word .L%d-.L%d\n", VALUE, REL)
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
+  fprintf (FILE, "\t.word .L%d\n", VALUE)
+
+\f
+/* Alignment Output */
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG)  \
+  do { if (LOG!=0) fprintf (FILE, "\t.align\t%d\n", (LOG)); } while (0)
+
+\f
+/* Misc */
+
+#define CASE_VECTOR_MODE SImode
+
+#define MOVE_MAX 16 
+
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) ((INPREC) <= 32 && (OUTPREC) <= (INPREC))
+
+#define STORE_FLAG_VALUE -1
+
+#define Pmode SImode
+
+#define FUNCTION_MODE QImode
+
+#define NO_IMPLICIT_EXTERN_C 1
+
+\f
+
+/* These are set by the cmp patterns and used while expanding
+   conditional branches. */
+extern GTY(()) rtx spu_compare_op0;
+extern GTY(()) rtx spu_compare_op1;
+
diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md
new file mode 100644 (file)
index 0000000..6ed9e7b
--- /dev/null
@@ -0,0 +1,3171 @@
+;; Copyright (C) 2006 Free Software Foundation, Inc.
+
+;; This file is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 2 of the License, or (at your option) 
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this file; see the file COPYING.  If not, write to the Free
+;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
+
+\f
+;; Define an insn type attribute.  This is used in function unit delay
+;; computations.
+;; multi0 is a multiple insn rtl whose first insn is in pipe0
+;; multi1 is a multiple insn rtl whose first insn is in pipe1
+(define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
+  (const_string "fx2"))
+
+;; Length (in bytes).
+(define_attr "length" ""
+               (const_int 4))
+
+;; Processor type -- this attribute must exactly match the processor_type
+;; enumeration in spu.h.
+
+(define_attr "cpu" "spu"
+  (const (symbol_ref "spu_cpu_attr")))
+
+; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
+;                      TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
+
+(define_cpu_unit "pipe0,pipe1,fp,ls")
+
+(define_insn_reservation "NOP" 1 (eq_attr "type" "nop")
+    "pipe0")
+
+(define_insn_reservation "FX2" 2 (eq_attr "type" "fx2")
+    "pipe0, nothing")
+
+(define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb")
+    "pipe0, nothing*3")
+
+(define_insn_reservation "FP6" 6 (eq_attr "type" "fp6")
+    "pipe0 + fp, nothing*5")
+
+(define_insn_reservation "FP7" 7 (eq_attr "type" "fp7")
+    "pipe0, fp, nothing*5")
+
+;; The behaviour of the double precision is that both pipes stall
+;; for 6 cycles and the the rest of the operation pipelines for
+;; 7 cycles.  The simplest way to model this is to simply ignore
+;; the 6 cyle stall.
+(define_insn_reservation "FPD" 7 (eq_attr "type" "fpd")
+    "pipe0 + pipe1, fp, nothing*5")
+
+(define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
+    "pipe1")
+
+(define_insn_reservation "STORE" 1 (eq_attr "type" "store")
+    "pipe1 + ls")
+
+(define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
+    "pipe1 + ls")
+
+(define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
+    "pipe1, nothing*3")
+
+(define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
+    "pipe1 + ls, nothing*5")
+
+(define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
+    "pipe1, nothing*15")
+
+(define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
+    "pipe0+pipe1, nothing*3")
+
+(define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
+    "pipe1, nothing*3")
+
+(define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
+    "nothing")
+
+;; Force pipe0 to occur before pipe 1 in a cycle.
+(absence_set "pipe0" "pipe1")
+
+\f
+(define_constants [
+ (UNSPEC_BLOCKAGE      0)
+ (UNSPEC_IPREFETCH     1)
+ (UNSPEC_FREST         2)
+ (UNSPEC_FRSQEST       3)
+ (UNSPEC_FI            4)
+ (UNSPEC_EXTEND_CMP    5)
+ (UNSPEC_CG            6)
+ (UNSPEC_CGX           7)
+ (UNSPEC_ADDX          8)
+ (UNSPEC_BG            9)
+ (UNSPEC_BGX           10)
+ (UNSPEC_SFX           11)
+ (UNSPEC_FSM           12)
+ (UNSPEC_HBR           13)
+ (UNSPEC_LNOP          14)
+ (UNSPEC_NOP           15)
+ (UNSPEC_CONVERT       16)
+ (UNSPEC_SELB          17)
+ (UNSPEC_SHUFB         18)
+ (UNSPEC_CPAT          19)
+ (UNSPEC_SYNC          20)
+ (UNSPEC_CNTB          21)
+ (UNSPEC_SUMB          22)
+ (UNSPEC_FSMB           23)
+ (UNSPEC_FSMH           24)
+ (UNSPEC_GBB            25)
+ (UNSPEC_GBH            26)
+ (UNSPEC_GB             27)
+ (UNSPEC_AVGB           28)
+ (UNSPEC_ABSDB          29)
+ (UNSPEC_ORX            30)
+ (UNSPEC_HEQ            31)
+ (UNSPEC_HGT            32)
+ (UNSPEC_HLGT           33)
+ (UNSPEC_CSFLT          34)
+ (UNSPEC_CFLTS          35)
+ (UNSPEC_CUFLT          36)
+ (UNSPEC_CFLTU          37)
+ (UNSPEC_STOP           38)
+ (UNSPEC_STOPD          39)
+ (UNSPEC_IDISABLE       40)
+ (UNSPEC_IENABLE        41)
+ (UNSPEC_FSCRRD         42)
+ (UNSPEC_FSCRWR         43)
+ (UNSPEC_MFSPR          44)
+ (UNSPEC_MTSPR          45)
+ (UNSPEC_RDCH           46)
+ (UNSPEC_RCHCNT         47)
+ (UNSPEC_WRCH           48)])
+
+(include "predicates.md")
+(include "constraints.md")
+
+\f
+;; Mode macros
+
+(define_mode_macro ALL [QI V16QI
+                       HI V8HI
+                       SI V4SI
+                       DI V2DI
+                       TI
+                        SF V4SF
+                        DF V2DF])
+
+; Everything except DI and TI which are handled separately because
+; they need different constraints to correctly test VOIDmode constants
+(define_mode_macro MOV [QI V16QI
+                       HI V8HI
+                       SI V4SI
+                       V2DI
+                        SF V4SF
+                        DF V2DF])
+
+(define_mode_macro DTI  [DI TI])
+
+(define_mode_macro VINT [QI V16QI
+                        HI V8HI
+                        SI V4SI
+                        DI V2DI
+                        TI])
+
+(define_mode_macro VQHSI [QI V16QI
+                         HI V8HI
+                         SI V4SI])
+
+(define_mode_macro VHSI [HI V8HI
+                        SI V4SI])
+
+(define_mode_macro VSDF [SF V4SF
+                         DF V2DF])
+
+(define_mode_macro VSI [SI V4SI])
+(define_mode_macro VDI [DI V2DI])
+(define_mode_macro VSF [SF V4SF])
+(define_mode_macro VDF [DF V2DF])
+
+(define_mode_attr bh  [(QI "b")  (V16QI "b")
+                      (HI "h")  (V8HI "h")
+                      (SI "")   (V4SI "")])
+
+(define_mode_attr d   [(SF "")   (V4SF "")
+                       (DF "d")  (V2DF "d")])
+(define_mode_attr d6  [(SF "6")  (V4SF "6")
+                       (DF "d")  (V2DF "d")])
+(define_mode_attr f2i [(SF "SI") (V4SF "V4SI")
+                       (DF "DI") (V2DF "V2DI")])
+
+;; Used for carry and borrow instructions.
+(define_mode_macro CBOP  [SI DI V4SI V2DI])
+
+;; Used in vec_set and vec_extract
+(define_mode_macro V [V2DI V4SI V8HI V16QI V2DF V4SF])
+(define_mode_attr inner  [(V16QI "QI")
+                         (V8HI  "HI")
+                         (V4SI  "SI")
+                         (V2DI  "DI")
+                         (V4SF  "SF")
+                         (V2DF  "DF")])
+(define_mode_attr vmult  [(V16QI "1")
+                         (V8HI  "2")
+                         (V4SI  "4")
+                         (V2DI  "8")
+                         (V4SF  "4")
+                         (V2DF  "8")])
+(define_mode_attr voff   [(V16QI "13")
+                         (V8HI  "14")
+                         (V4SI  "0")
+                         (V2DI  "0")
+                         (V4SF  "0")
+                         (V2DF  "0")])
+
+\f
+;; mov
+
+(define_expand "mov<mode>"
+  [(set (match_operand:ALL 0 "spu_nonimm_operand" "=r,r,r,m")
+       (match_operand:ALL 1 "general_operand" "r,i,m,r"))]
+  ""
+  {
+    if (spu_expand_mov(operands, <MODE>mode))
+      DONE;
+  })
+
+(define_insn "pic"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (match_operand:SI 1 "immediate_operand" "s"))
+   (use (const_int 0))]
+  "flag_pic"
+  "ila\t%0,%%pic(%1)")
+
+;; Whenever a function generates the 'pic' pattern above we need to
+;; load the pic_offset_table register.
+;; GCC doesn't deal well with labels in the middle of a block so we
+;; hardcode the offsets in the asm here.
+(define_insn "load_pic_offset"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (unspec:SI [(const_int 0)] 0))
+   (set (match_operand:SI 1 "spu_reg_operand" "=r")
+       (unspec:SI [(const_int 0)] 0))]
+  "flag_pic"
+  "ila\t%1,.+8\;brsl\t%0,4"
+  [(set_attr "length" "8")
+   (set_attr "type" "multi0")])
+
+\f
+;; move internal
+
+(define_insn "_mov<mode>"
+  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
+       (match_operand:MOV 1 "spu_nonmem_operand" "r,A,f"))]
+  ""
+  "@
+   ori\t%0,%1,0
+   il%s1\t%0,%S1
+   fsmbi\t%0,%F1"
+  [(set_attr "type" "fx2,fx2,shuf")])
+
+(define_insn "high"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
+  ""
+  "ilhu\t%0,%1@h")
+
+(define_insn "low"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (lo_sum:SI (match_operand:SI 1 "spu_reg_operand" "0")
+                  (match_operand:SI 2 "immediate_operand" "i")))]
+  ""
+  "iohl\t%0,%2@l")
+
+(define_insn "_movdi"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
+       (match_operand:DI 1 "spu_nonmem_operand" "r,a,f"))]
+  ""
+  "@
+   ori\t%0,%1,0
+   il%d1\t%0,%D1
+   fsmbi\t%0,%G1"
+  [(set_attr "type" "fx2,fx2,shuf")])
+
+(define_insn "_movti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
+       (match_operand:TI 1 "spu_nonmem_operand" "r,U,f"))]
+  ""
+  "@
+   ori\t%0,%1,0
+   il%t1\t%0,%T1
+   fsmbi\t%0,%H1"
+  [(set_attr "type" "fx2,fx2,shuf")])
+
+(define_insn_and_split "load"
+  [(set (match_operand 0 "spu_reg_operand" "=r")
+       (match_operand 1 "memory_operand" "m"))
+   (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
+   (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))]
+  "GET_MODE(operands[0]) == GET_MODE(operands[1])"
+  "#"
+  ""
+  [(set (match_dup 0)
+       (match_dup 1))]
+  { spu_split_load(operands); DONE; })
+
+(define_insn "lq"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+       (mem:TI (and:SI (match_operand:SI 1 "address_operand" "p")
+                       (const_int -16))))]
+  ""
+  "lq%p1\t%0,%a1"
+  [(set_attr "type" "load")])
+
+(define_insn "lq_<mode>"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
+       (match_operand:ALL 1 "spu_mem_operand" "m"))]
+  "spu_valid_move (operands)"
+  "lq%p1\t%0,%1"
+  [(set_attr "type" "load")])
+
+
+(define_insn_and_split "store"
+  [(set (match_operand 0 "memory_operand" "=m")
+       (match_operand 1 "spu_reg_operand" "r"))
+   (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
+   (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
+  "GET_MODE(operands[0]) == GET_MODE(operands[1])"
+  "#"
+  ""
+  [(set (match_dup 0)
+       (match_dup 1))]
+  { spu_split_store(operands); DONE; })
+
+(define_insn "stq"
+  [(set (mem:TI (and:SI (match_operand:SI 0 "address_operand" "p")
+                       (const_int -16)))
+       (match_operand:TI 1 "spu_reg_operand" "r"))]
+  ""
+  "stq%p0\t%1,%a0"
+  [(set_attr "type" "load")])
+
+(define_insn "stq_<mode>"
+  [(set (match_operand:ALL 0 "spu_mem_operand" "=m")
+       (match_operand:ALL 1 "spu_reg_operand" "r"))]
+  "spu_valid_move (operands)"
+  "stq%p0\t%1,%0"
+  [(set_attr "type" "load")])
+
+;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
+(define_insn "cpat"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+        (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
+                    (match_operand:SI 2 "spu_nonmem_operand" "r,n")
+                   (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
+  ""
+  "@
+   c%M3x\t%0,%1,%2
+   c%M3d\t%0,%C2(%1)"
+  [(set_attr "type" "shuf")])
+
+\f
+;; extend
+
+(define_insn "extendqihi2"
+  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
+       (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
+  ""
+  "xsbh\t%0,%1")
+
+(define_insn "extendhisi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
+  ""
+  "xshw\t%0,%1")
+
+(define_expand "extendsidi2"
+  [(set (match_dup:DI 2)
+       (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
+   (set (match_operand:DI 0 "spu_reg_operand" "")
+       (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
+                                      (parallel [(const_int 1)]))))]
+  ""
+  {
+    operands[2] = gen_reg_rtx (DImode);
+    operands[3] = spu_gen_subreg (V2SImode, operands[2]);
+  })
+
+(define_insn "xswd"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
+       (sign_extend:DI
+         (vec_select:SI
+           (match_operand:V2SI 1 "spu_reg_operand" "r")
+           (parallel [(const_int 1) ]))))]
+  ""
+  "xswd\t%0,%1");
+
+(define_expand "extendqiti2"
+  [(set (match_operand:TI 0 "register_operand" "")
+       (sign_extend:TI (match_operand:QI 1 "register_operand" "")))]
+  ""
+  "spu_expand_sign_extend(operands);
+   DONE;")
+
+(define_expand "extendhiti2"
+  [(set (match_operand:TI 0 "register_operand" "")
+       (sign_extend:TI (match_operand:HI 1 "register_operand" "")))]
+  ""
+  "spu_expand_sign_extend(operands);
+   DONE;")
+
+(define_expand "extendsiti2"
+  [(set (match_operand:TI 0 "register_operand" "")
+       (sign_extend:TI (match_operand:SI 1 "register_operand" "")))]
+  ""
+  "spu_expand_sign_extend(operands);
+   DONE;")
+
+(define_expand "extendditi2"
+  [(set (match_operand:TI 0 "register_operand" "")
+       (sign_extend:TI (match_operand:DI 1 "register_operand" "")))]
+  ""
+  "spu_expand_sign_extend(operands);
+   DONE;")
+
+\f
+;; zero_extend
+
+(define_insn "zero_extendqihi2"
+  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
+       (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
+  ""
+  "andi\t%0,%1,0x00ff")
+
+(define_insn "zero_extendqisi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
+  ""
+  "andi\t%0,%1,0x00ff")
+
+(define_insn_and_split "zero_extendhisi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
+   (clobber (match_scratch:SI 2 "=&r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:SI 2)
+        (const_int 65535))
+   (set (match_dup:SI 0)
+        (and:SI (match_dup:SI 3)
+                (match_dup:SI 2)))]
+  "operands[3] = gen_rtx_REG (SImode, REGNO (operands[1]));")
+
+(define_insn "zero_extendsidi2"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
+       (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
+  ""
+  "rotqmbyi\t%0,%1,-4"
+  [(set_attr "type" "shuf")])
+
+(define_insn "zero_extendsiti2"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+       (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
+  ""
+  "rotqmbyi\t%0,%1,-12"
+  [(set_attr "type" "shuf")])
+
+(define_insn "zero_extendditi2"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+       (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
+  ""
+  "rotqmbyi\t%0,%1,-8"
+  [(set_attr "type" "shuf")])
+
+\f
+;; trunc
+
+(define_insn "truncdiqi2"
+  [(set (match_operand:QI 0 "spu_reg_operand" "=r")
+       (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
+  ""
+  "shlqbyi\t%0,%1,4"
+  [(set_attr "type" "shuf")])
+
+(define_insn "truncdihi2"
+  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
+       (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
+  ""
+  "shlqbyi\t%0,%1,4"
+  [(set_attr "type" "shuf")])
+
+(define_insn "truncdisi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
+  ""
+  "shlqbyi\t%0,%1,4"
+  [(set_attr "type" "shuf")])
+
+(define_insn "trunctiqi2"
+  [(set (match_operand:QI 0 "spu_reg_operand" "=r")
+       (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
+  ""
+  "shlqbyi\t%0,%1,12"
+  [(set_attr "type" "shuf")])
+
+(define_insn "trunctihi2"
+  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
+       (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
+  ""
+  "shlqbyi\t%0,%1,12"
+  [(set_attr "type" "shuf")])
+
+(define_insn "trunctisi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
+  ""
+  "shlqbyi\t%0,%1,12"
+  [(set_attr "type" "shuf")])
+
+(define_insn "trunctidi2"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
+       (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
+  ""
+  "shlqbyi\t%0,%1,8"
+  [(set_attr "type" "shuf")])
+
+\f
+;; float conversions
+
+(define_insn "floatsisf2"
+  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
+       (float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
+  ""
+  "csflt\t%0,%1,0"
+  [(set_attr "type" "fp7")])
+
+(define_insn "fix_truncsfsi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
+  ""
+  "cflts\t%0,%1,0"
+  [(set_attr "type" "fp7")])
+
+(define_insn "floatunssisf2"
+  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
+       (unsigned_float:SF (match_operand:SI 1 "spu_reg_operand" "r")))]
+  ""
+  "cuflt\t%0,%1,0"
+  [(set_attr "type" "fp7")])
+
+(define_insn "fixuns_truncsfsi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (unsigned_fix:SI (match_operand:SF 1 "spu_reg_operand" "r")))]
+  ""
+  "cfltu\t%0,%1,0"
+  [(set_attr "type" "fp7")])
+
+(define_insn "extendsfdf2"
+  [(set (match_operand:DF 0 "spu_reg_operand" "=r")
+       (float_extend:DF (match_operand:SF 1 "spu_reg_operand" "r")))]
+  ""
+  "fesd\t%0,%1"
+  [(set_attr "type" "fpd")])
+
+(define_insn "truncdfsf2"
+  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
+       (float_truncate:SF (match_operand:DF 1 "spu_reg_operand" "r")))]
+  ""
+  "frds\t%0,%1"
+  [(set_attr "type" "fpd")])
+
+;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
+(define_expand "floatsidf2"
+  [(set (match_operand:DF 0 "register_operand" "")
+       (float:DF (match_operand:SI 1 "register_operand" "")))]
+  ""
+  {
+    rtx value, insns;
+    rtx c0 = gen_reg_rtx (SImode);
+    rtx c1 = gen_reg_rtx (DFmode);
+    rtx r0 = gen_reg_rtx (SImode);
+    rtx r1 = gen_reg_rtx (DFmode);
+
+    emit_move_insn (c0, GEN_INT (-0x80000000ll));
+    emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
+
+    emit_insn (gen_xorsi3 (r0, operands[1], c0));
+
+    start_sequence ();
+    value =
+      emit_library_call_value (ufloat_optab->handlers[DFmode][SImode].libfunc,
+                              NULL_RTX, LCT_NORMAL, DFmode, 1, r0, SImode);
+    insns = get_insns ();
+    end_sequence ();
+    emit_libcall_block (insns, r1, value,
+                       gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
+
+    emit_insn (gen_subdf3 (operands[0], r1, c1));
+    DONE;
+  })
+
+(define_expand "floatdidf2"
+  [(set (match_operand:DF 0 "register_operand" "")
+       (float:DF (match_operand:DI 1 "register_operand" "")))]
+  ""
+  {
+    rtx value, insns;
+    rtx c0 = gen_reg_rtx (DImode);
+    rtx r0 = gen_reg_rtx (DImode);
+    rtx r1 = gen_reg_rtx (DFmode);
+    rtx r2 = gen_reg_rtx (DImode);
+    rtx setneg = gen_reg_rtx (DImode);
+    rtx isneg = gen_reg_rtx (SImode);
+    rtx neg = gen_reg_rtx (DImode);
+    rtx mask = gen_reg_rtx (DImode);
+
+    emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
+
+    emit_insn (gen_negdi2 (neg, operands[1]));
+    emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
+    emit_insn (gen_extend_compare (mask, isneg));
+    emit_insn (gen_selb (r0, neg, operands[1], mask));
+    emit_insn (gen_andc_di (setneg, c0, mask));
+
+
+    start_sequence ();
+    value =
+      emit_library_call_value (ufloat_optab->handlers[DFmode][DImode].libfunc,
+                              NULL_RTX, LCT_NORMAL, DFmode, 1, r0, DImode);
+    insns = get_insns ();
+    end_sequence ();
+    emit_libcall_block (insns, r1, value,
+                       gen_rtx_UNSIGNED_FLOAT (DFmode, r0));
+
+    emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
+    emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
+    DONE;
+  })
+\f
+;; add
+
+(define_insn "add<mode>3"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
+                  (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
+  ""
+  "@
+  a<bh>\t%0,%1,%2
+  a<bh>i\t%0,%1,%2")
+
+(define_expand "add<mode>3"
+  [(set (match_dup:VDI 3) 
+       (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
+                    (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
+   (set (match_dup:VDI 5)
+       (unspec:VDI [(match_dup 3)
+                    (match_dup 3)
+                    (match_dup:TI 4)] UNSPEC_SHUFB))
+   (set (match_operand:VDI 0 "spu_reg_operand" "") 
+       (unspec:VDI [(match_dup 1)
+                    (match_dup 2)
+                    (match_dup 5)] UNSPEC_ADDX))]
+  ""
+  {
+    unsigned char pat[16] = {
+      0x04, 0x05, 0x06, 0x07,
+      0x80, 0x80, 0x80, 0x80,
+      0x0c, 0x0d, 0x0e, 0x0f,
+      0x80, 0x80, 0x80, 0x80
+    };
+    operands[3] = gen_reg_rtx (<MODE>mode);
+    operands[4] = gen_reg_rtx (TImode);
+    operands[5] = gen_reg_rtx (<MODE>mode);
+    emit_move_insn (operands[4], array_to_constant (TImode, pat));
+  })
+
+(define_insn "cg_<mode>"
+  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
+       (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
+                     (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
+  "operands"
+  "cg\t%0,%1,%2")
+
+(define_insn "cgx_<mode>"
+  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
+       (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
+                     (match_operand 2 "spu_reg_operand" "r")
+                     (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
+  "operands"
+  "cgx\t%0,%1,%2")
+
+(define_insn "addx_<mode>"
+  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
+       (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
+                     (match_operand 2 "spu_reg_operand" "r")
+                     (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
+  "operands"
+  "addx\t%0,%1,%2")
+
+
+;; This is not the most efficient implementation of addti3.
+;; We include this here because 1) the compiler needs it to be
+;; defined as the word size is 128-bit and 2) sometimes gcc
+;; substitutes an add for a constant left-shift. 2) is unlikely
+;; because we also give addti3 a high cost. In case gcc does
+;; generate TImode add, here is the code to do it.
+;; operand 2 is a nonmemory because the compiler requires it.
+(define_insn "addti3"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
+       (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
+                (match_operand:TI 2 "spu_nonmem_operand" "r")))
+   (clobber (match_scratch:TI 3 "=&r"))]
+  ""
+  "cg\t%3,%1,%2\n\\
+   shlqbyi\t%3,%3,4\n\\
+   cgx\t%3,%1,%2\n\\
+   shlqbyi\t%3,%3,4\n\\
+   cgx\t%3,%1,%2\n\\
+   shlqbyi\t%0,%3,4\n\\
+   addx\t%0,%1,%2"
+  [(set_attr "type" "multi0")
+   (set_attr "length" "28")])
+
+(define_insn "add<mode>3"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                 (match_operand:VSF 2 "spu_reg_operand" "r")))]
+  ""
+  "fa\t%0,%1,%2"
+  [(set_attr "type" "fp6")])
+
+(define_insn "add<mode>3"
+  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
+       (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
+                 (match_operand:VDF 2 "spu_reg_operand" "r")))]
+  ""
+  "dfa\t%0,%1,%2"
+  [(set_attr "type" "fpd")])
+
+\f
+;; sub
+
+(define_insn "sub<mode>3"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
+                   (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
+  ""
+  "@
+  sf<bh>\t%0,%2,%1
+  sf<bh>i\t%0,%2,%1")
+
+(define_expand "sub<mode>3"
+  [(set (match_dup:VDI 3) 
+       (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
+                    (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
+   (set (match_dup:VDI 5)
+       (unspec:VDI [(match_dup 3)
+                    (match_dup 3)
+                    (match_dup:TI 4)] UNSPEC_SHUFB))
+   (set (match_operand:VDI 0 "spu_reg_operand" "") 
+       (unspec:VDI [(match_dup 1)
+                    (match_dup 2)
+                    (match_dup 5)] UNSPEC_SFX))]
+  ""
+  {
+    unsigned char pat[16] = {
+      0x04, 0x05, 0x06, 0x07,
+      0xc0, 0xc0, 0xc0, 0xc0,
+      0x0c, 0x0d, 0x0e, 0x0f,
+      0xc0, 0xc0, 0xc0, 0xc0
+    };
+    operands[3] = gen_reg_rtx (<MODE>mode);
+    operands[4] = gen_reg_rtx (TImode);
+    operands[5] = gen_reg_rtx (<MODE>mode);
+    emit_move_insn (operands[4], array_to_constant (TImode, pat));
+  })
+
+(define_insn "bg_<mode>"
+  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
+       (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
+                     (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
+  "operands"
+  "bg\t%0,%2,%1")
+
+(define_insn "bgx_<mode>"
+  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
+       (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
+                     (match_operand 2 "spu_reg_operand" "r")
+                     (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
+  "operands"
+  "bgx\t%0,%2,%1")
+
+(define_insn "sfx_<mode>"
+  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
+       (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
+                     (match_operand 2 "spu_reg_operand" "r")
+                     (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
+  "operands"
+  "sfx\t%0,%2,%1")
+
+(define_insn "subti3"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+       (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
+                 (match_operand:TI 2 "spu_reg_operand" "r")))
+   (clobber (match_scratch:TI 3 "=&r"))
+   (clobber (match_scratch:TI 4 "=&r"))
+   (clobber (match_scratch:TI 5 "=&r"))]
+  ""
+  "bg\t%3,%1,%2\n\\
+   sf\t%4,%2,%1\n\\
+   shlqbyi\t%5,%3,4\n\\
+   bg\t%3,%4,%5\n\\
+   sf\t%4,%5,%4\n\\
+   shlqbyi\t%5,%3,4\n\\
+   bg\t%3,%4,%5\n\\
+   shlqbyi\t%0,%3,4\n\\
+   sfx\t%0,%5,%4"
+  [(set_attr "type" "multi0")
+   (set_attr "length" "36")])
+
+(define_insn "sub<mode>3"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                  (match_operand:VSF 2 "spu_reg_operand" "r")))]
+  ""
+  "fs\t%0,%1,%2"
+  [(set_attr "type" "fp6")])
+
+(define_insn "sub<mode>3"
+  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
+       (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
+                  (match_operand:VDF 2 "spu_reg_operand" "r")))]
+  ""
+  "dfs\t%0,%1,%2"
+  [(set_attr "type" "fpd")])
+
+\f
+;; neg
+
+(define_insn "neg<mode>2"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
+       (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
+  ""
+  "sf<bh>i\t%0,%1,0")
+
+(define_expand "negdi2"
+  [(set (match_operand:DI 0 "spu_reg_operand" "")
+       (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
+  ""
+  {
+    rtx zero = gen_reg_rtx(DImode);
+    emit_move_insn(zero, GEN_INT(0));
+    emit_insn(gen_subdi3(operands[0], zero, operands[1]));
+    DONE;
+  })
+
+(define_expand "negti2"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+       (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
+  ""
+  {
+    rtx zero = gen_reg_rtx(TImode);
+    emit_move_insn(zero, GEN_INT(0));
+    emit_insn(gen_subti3(operands[0], zero, operands[1]));
+    DONE;
+  })
+
+(define_expand "neg<mode>2"
+  [(parallel
+    [(set (match_operand:VSF 0 "spu_reg_operand" "")
+         (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
+     (use (match_dup 2))])]
+  ""
+  "operands[2] = gen_reg_rtx (<f2i>mode);
+   emit_move_insn (operands[2], spu_const (<f2i>mode, -0x80000000ull));")
+
+(define_expand "neg<mode>2"
+  [(parallel
+    [(set (match_operand:VDF 0 "spu_reg_operand" "")
+         (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
+     (use (match_dup 2))])]
+  ""
+  "operands[2] = gen_reg_rtx (<f2i>mode);
+   emit_move_insn (operands[2], spu_const (<f2i>mode, -0x8000000000000000ull));")
+
+(define_insn_and_split "_neg<mode>2"
+  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
+       (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
+   (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
+  ""
+  "#"
+  ""
+  [(set (match_dup:<f2i> 3)
+       (xor:<f2i> (match_dup:<f2i> 4)
+                  (match_dup:<f2i> 2)))]
+  {
+    operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
+    operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
+  })
+
+\f
+;; abs
+
+(define_expand "abs<mode>2"
+  [(parallel
+    [(set (match_operand:VSF 0 "spu_reg_operand" "")
+         (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
+     (use (match_dup 2))])]
+  ""
+  "operands[2] = gen_reg_rtx (<f2i>mode);
+   emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffull));")
+
+(define_expand "abs<mode>2"
+  [(parallel
+    [(set (match_operand:VDF 0 "spu_reg_operand" "")
+         (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
+     (use (match_dup 2))])]
+  ""
+  "operands[2] = gen_reg_rtx (<f2i>mode);
+   emit_move_insn (operands[2], spu_const (<f2i>mode, 0x7fffffffffffffffull));")
+
+(define_insn_and_split "_abs<mode>2"
+  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
+       (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
+   (use (match_operand:<f2i> 2 "spu_reg_operand" "r"))]
+  ""
+  "#"
+  ""
+  [(set (match_dup:<f2i> 3)
+       (and:<f2i> (match_dup:<f2i> 4)
+                  (match_dup:<f2i> 2)))]
+  {
+    operands[3] = spu_gen_subreg (<f2i>mode, operands[0]);
+    operands[4] = spu_gen_subreg (<f2i>mode, operands[1]);
+  })
+
+\f
+;; mul
+
+(define_insn "mulhi3"
+  [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
+       (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
+                (match_operand:HI 2 "spu_arith_operand" "r,B")))]
+  ""
+  "@
+  mpy\t%0,%1,%2
+  mpyi\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_expand "mulsi3"
+  [(parallel
+    [(set (match_operand:SI 0 "spu_reg_operand" "")
+         (mult:SI (match_operand:SI 1 "spu_reg_operand" "")
+                  (match_operand:SI 2 "spu_reg_operand" "")))
+     (clobber (match_dup:SI 3))
+     (clobber (match_dup:SI 4))
+     (clobber (match_dup:SI 5))
+     (clobber (match_dup:SI 6))])]
+  ""
+  {
+    operands[3] = gen_reg_rtx(SImode);
+    operands[4] = gen_reg_rtx(SImode);
+    operands[5] = gen_reg_rtx(SImode);
+    operands[6] = gen_reg_rtx(SImode);
+  })
+
+(define_insn_and_split "_mulsi3"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
+                (match_operand:SI 2 "spu_nonmem_operand" "ri")))
+   (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
+   (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
+   (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
+   (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
+  ""
+  "#"
+  ""
+  [(set (match_dup:SI 0)
+       (mult:SI (match_dup:SI 1)
+                (match_dup:SI 2)))]
+  {
+    HOST_WIDE_INT val = 0;
+    rtx a = operands[3];
+    rtx b = operands[4];
+    rtx c = operands[5];
+    rtx d = operands[6];
+    if (GET_CODE(operands[2]) == CONST_INT)
+      {
+       val = INTVAL(operands[2]);
+       emit_move_insn(d, operands[2]);
+       operands[2] = d;
+      }
+    if (val && (val & 0xffff) == 0)
+      {
+       emit_insn(gen_mpyh_si(operands[0], operands[2], operands[1]));
+      }
+    else if (val > 0 && val < 0x10000)
+      {
+       rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
+       emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
+       emit_insn(gen_mpyu_si(c, operands[1], cst));
+       emit_insn(gen_addsi3(operands[0], a, c));
+      }
+    else
+      {
+       emit_insn(gen_mpyh_si(a, operands[1], operands[2]));
+       emit_insn(gen_mpyh_si(b, operands[2], operands[1]));
+       emit_insn(gen_mpyu_si(c, operands[1], operands[2]));
+       emit_insn(gen_addsi3(d, a, b));
+       emit_insn(gen_addsi3(operands[0], d, c));
+      }
+    DONE;
+   })
+
+(define_insn "mulhisi3"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
+                (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
+  ""
+  "mpy\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mulhisi3_imm"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
+                (match_operand:SI 2 "immediate_operand" "K")))]
+  ""
+  "mpyi\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "umulhisi3"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
+                (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
+  ""
+  "mpyu\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "umulhisi3_imm"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
+                (and:SI (match_operand:SI 2 "immediate_operand" "K") (const_int 65535))))]
+  ""
+  "mpyui\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mpyu_si"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
+       (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
+                        (const_int 65535))
+                (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
+                        (const_int 65535))))]
+  ""
+  "@
+   mpyu\t%0,%1,%2
+   mpyui\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+;; This isn't always profitable to use.  Consider r = a * b + c * d.
+;; It's faster to do  the multplies in parallel then add them.  If we
+;; merge a multply and add it prevents the multplies from happening in 
+;; parallel.
+(define_insn "mpya_si"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
+                         (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
+                (match_operand:SI 3 "spu_reg_operand" "r")))]
+  "0"
+  "mpya\t%0,%1,%2,%3"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mpyh_si"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
+                        (const_int -65536))
+                (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
+                        (const_int 65535))))]
+  ""
+  "mpyh\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mpys_si"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (ashiftrt:SI
+           (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
+                    (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
+           (const_int 16)))]
+  ""
+  "mpys\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mpyhh_si"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
+                             (const_int 16))
+                (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
+                             (const_int 16))))]
+  ""
+  "mpyhh\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mpyhhu_si"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
+                             (const_int 16))
+                (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
+                             (const_int 16))))]
+  ""
+  "mpyhhu\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mpyhha_si" 
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
+                                      (const_int 16))
+                         (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
+                                      (const_int 16)))
+                (match_operand:SI 3 "spu_reg_operand" "0")))]
+  "0"
+  "mpyhha\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+(define_insn "mul<mode>3"
+  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
+       (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
+                  (match_operand:VSDF 2 "spu_reg_operand" "r")))]
+  ""
+  "<d>fm\t%0,%1,%2"
+  [(set_attr "type" "fp<d6>")])
+
+(define_insn "fma_<mode>"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                             (match_operand:VSF 2 "spu_reg_operand" "r"))
+                  (match_operand:VSF 3 "spu_reg_operand" "r")))]
+  ""
+  "fma\t%0,%1,%2,%3"
+  [(set_attr "type"    "fp6")])
+
+(define_insn "fnms_<mode>"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
+                   (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                              (match_operand:VSF 2 "spu_reg_operand" "r"))))]
+  ""
+  "fnms\t%0,%1,%2,%3"
+  [(set_attr "type" "fp6")])
+
+(define_insn "fms_<mode>"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                              (match_operand:VSF 2 "spu_reg_operand" "r"))
+                   (match_operand:VSF 3 "spu_reg_operand" "r")))]
+  ""
+  "fms\t%0,%1,%2,%3"
+  [(set_attr "type" "fp6")])
+
+(define_insn "fma_<mode>"
+  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
+       (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
+                           (match_operand:VDF 2 "spu_reg_operand" "r"))
+                 (match_operand:VDF 3 "spu_reg_operand" "0")))]
+  ""
+  "dfma\t%0,%1,%2"
+  [(set_attr "type"    "fpd")])
+
+(define_insn "fnma_<mode>"
+  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
+       (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
+                                    (match_operand:VDF 2 "spu_reg_operand" "r"))
+                          (match_operand:VDF 3 "spu_reg_operand" "0"))))]
+  ""
+  "dfnma\t%0,%1,%2"
+  [(set_attr "type"    "fpd")])
+
+(define_insn "fnms_<mode>"
+  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
+       (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
+                  (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
+                            (match_operand:VDF 2 "spu_reg_operand" "r"))))]
+  ""
+  "dfnms\t%0,%1,%2"
+  [(set_attr "type" "fpd")])
+
+(define_insn "fms_<mode>"
+  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
+       (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
+                            (match_operand:VDF 2 "spu_reg_operand" "r"))
+                  (match_operand:VDF 3 "spu_reg_operand" "0")))]
+  ""
+  "dfms\t%0,%1,%2"
+  [(set_attr "type" "fpd")])
+
+\f
+;; mul highpart, used for divide by constant optimizations.
+
+(define_expand "smulsi3_highpart"
+  [(set (match_operand:SI 0 "register_operand" "")
+       (truncate:SI
+         (ashiftrt:DI
+           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
+                    (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
+           (const_int 32))))]
+  ""
+  {
+    rtx t0 = gen_reg_rtx (SImode);
+    rtx t1 = gen_reg_rtx (SImode);
+    rtx t2 = gen_reg_rtx (SImode);
+    rtx t3 = gen_reg_rtx (SImode);
+    rtx t4 = gen_reg_rtx (SImode);
+    rtx t5 = gen_reg_rtx (SImode);
+    rtx t6 = gen_reg_rtx (SImode);
+    rtx t7 = gen_reg_rtx (SImode);
+    rtx t8 = gen_reg_rtx (SImode);
+    rtx t9 = gen_reg_rtx (SImode);
+    rtx t11 = gen_reg_rtx (SImode);
+    rtx t12 = gen_reg_rtx (SImode);
+    rtx t14 = gen_reg_rtx (SImode);
+    rtx t15 = gen_reg_rtx (HImode);
+    rtx t16 = gen_reg_rtx (HImode);
+    rtx t17 = gen_reg_rtx (HImode);
+    rtx t18 = gen_reg_rtx (HImode);
+    rtx t19 = gen_reg_rtx (SImode);
+    rtx t20 = gen_reg_rtx (SImode);
+    rtx t21 = gen_reg_rtx (SImode);
+    rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
+    rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
+    rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
+    rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
+
+    emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
+    emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
+    emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
+    emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
+    emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
+    emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
+    emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
+    emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
+
+    /* Gen carry bits (in t9 and t11). */
+    emit_insn (gen_addsi3 (t8, t2, t3));
+    emit_insn (gen_cg_si (t9, t2, t3));
+    emit_insn (gen_cg_si (t11, t8, t4));
+
+    /* Gen high 32 bits in operand[0].  Correct for mpys. */
+    emit_insn (gen_addx_si (t12, t5, t6, t9));
+    emit_insn (gen_addx_si (t14, t12, t7, t11));
+
+    /* mpys treats both operands as signed when we really want it to treat
+       the first operand as signed and the second operand as unsigned.
+       The code below corrects for that difference.  */
+    emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
+    emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
+    emit_insn (gen_andc_hi (t17, t1_hi, t15));
+    emit_insn (gen_andc_hi (t18, t0_hi, t16));
+    emit_insn (gen_extendhisi2 (t19, t17));
+    emit_insn (gen_extendhisi2 (t20, t18));
+    emit_insn (gen_addsi3 (t21, t19, t20));
+    emit_insn (gen_addsi3 (operands[0], t14, t21));
+    DONE;
+  })
+
+(define_expand "umulsi3_highpart"
+  [(set (match_operand:SI 0 "register_operand" "")
+       (truncate:SI
+         (ashiftrt:DI
+           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
+                    (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
+           (const_int 32))))]
+  ""
+  
+  {
+    rtx t0 = gen_reg_rtx (SImode);
+    rtx t1 = gen_reg_rtx (SImode);
+    rtx t2 = gen_reg_rtx (SImode);
+    rtx t3 = gen_reg_rtx (SImode);
+    rtx t4 = gen_reg_rtx (SImode);
+    rtx t5 = gen_reg_rtx (SImode);
+    rtx t6 = gen_reg_rtx (SImode);
+    rtx t7 = gen_reg_rtx (SImode);
+    rtx t8 = gen_reg_rtx (SImode);
+    rtx t9 = gen_reg_rtx (SImode);
+    rtx t10 = gen_reg_rtx (SImode);
+    rtx t12 = gen_reg_rtx (SImode);
+    rtx t13 = gen_reg_rtx (SImode);
+    rtx t14 = gen_reg_rtx (SImode);
+    rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
+    rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
+    rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
+
+    emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
+    emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
+    emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
+    emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
+    emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
+    emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
+    emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
+    emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
+    emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
+
+    /* Gen carry bits (in t10 and t12). */
+    emit_insn (gen_addsi3 (t9, t1, t5));
+    emit_insn (gen_cg_si (t10, t1, t5));
+    emit_insn (gen_cg_si (t12, t9, t6));
+
+    /* Gen high 32 bits in operand[0]. */
+    emit_insn (gen_addx_si (t13, t4, t7, t10));
+    emit_insn (gen_addx_si (t14, t13, t8, t12));
+    emit_insn (gen_movsi (operands[0], t14));
+
+    DONE;
+  })
+\f
+;; div
+
+;; Not necessarily the best implementation of divide but faster then
+;; the default that gcc provides because this is inlined and it uses
+;; clz.
+(define_insn "divmodsi4"
+      [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
+           (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
+                   (match_operand:SI 2 "spu_reg_operand" "r")))
+       (set (match_operand:SI 3 "spu_reg_operand" "=&r")
+           (mod:SI (match_dup 1)
+                   (match_dup 2)))
+       (clobber (match_scratch:SI 4 "=&r"))
+       (clobber (match_scratch:SI 5 "=&r"))
+       (clobber (match_scratch:SI 6 "=&r"))
+       (clobber (match_scratch:SI 7 "=&r"))
+       (clobber (match_scratch:SI 8 "=&r"))
+       (clobber (match_scratch:SI 9 "=&r"))
+       (clobber (match_scratch:SI 10 "=&r"))
+       (clobber (match_scratch:SI 11 "=&r"))
+       (clobber (match_scratch:SI 12 "=&r"))
+       (clobber (reg:SI 130))]
+  ""
+  "heqi        %2,0\\n\\
+       hbrr    3f,1f\\n\\
+       sfi     %8,%1,0\\n\\
+       sfi     %9,%2,0\\n\\
+       cgti    %10,%1,-1\\n\\
+       cgti    %11,%2,-1\\n\\
+       selb    %8,%8,%1,%10\\n\\
+       selb    %9,%9,%2,%11\\n\\
+       clz     %4,%8\\n\\
+       clz     %7,%9\\n\\
+       il      %5,1\\n\\
+       fsmbi   %0,0\\n\\
+       sf      %7,%4,%7\\n\\
+       shlqbyi %3,%8,0\\n\\
+       xor     %11,%10,%11\\n\\
+       shl     %5,%5,%7\\n\\
+       shl     %4,%9,%7\\n\\
+       lnop    \\n\\
+1:     or      %12,%0,%5\\n\\
+       rotqmbii        %5,%5,-1\\n\\
+       clgt    %6,%4,%3\\n\\
+       lnop    \\n\\
+       sf      %7,%4,%3\\n\\
+       rotqmbii        %4,%4,-1\\n\\
+       selb    %0,%12,%0,%6\\n\\
+       lnop    \\n\\
+       selb    %3,%7,%3,%6\\n\\
+3:     brnz    %5,1b\\n\\
+2:     sfi     %8,%3,0\\n\\
+       sfi     %9,%0,0\\n\\
+       selb    %3,%8,%3,%10\\n\\
+       selb    %0,%0,%9,%11"
+  [(set_attr "type" "multi0")
+   (set_attr "length" "128")])
+
+(define_insn "udivmodsi4"
+      [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
+           (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
+                    (match_operand:SI 2 "spu_reg_operand" "r")))
+       (set (match_operand:SI 3 "spu_reg_operand" "=&r")
+           (umod:SI (match_dup 1)
+                    (match_dup 2)))
+       (clobber (match_scratch:SI 4 "=&r"))
+       (clobber (match_scratch:SI 5 "=&r"))
+       (clobber (match_scratch:SI 6 "=&r"))
+       (clobber (match_scratch:SI 7 "=&r"))
+       (clobber (match_scratch:SI 8 "=&r"))
+       (clobber (reg:SI 130))]
+  ""
+  "heqi        %2,0\\n\\
+       hbrr    3f,1f\\n\\
+       clz     %7,%2\\n\\
+       clz     %4,%1\\n\\
+       il      %5,1\\n\\
+       fsmbi   %0,0\\n\\
+       sf      %7,%4,%7\\n\\
+       ori     %3,%1,0\\n\\
+       shl     %5,%5,%7\\n\\
+       shl     %4,%2,%7\\n\\
+1:     or      %8,%0,%5\\n\\
+       rotqmbii        %5,%5,-1\\n\\
+       clgt    %6,%4,%3\\n\\
+       lnop    \\n\\
+       sf      %7,%4,%3\\n\\
+       rotqmbii        %4,%4,-1\\n\\
+       selb    %0,%8,%0,%6\\n\\
+       lnop    \\n\\
+       selb    %3,%7,%3,%6\\n\\
+3:     brnz    %5,1b\\n\\
+2:"
+  [(set_attr "type" "multi0")
+   (set_attr "length" "80")])
+
+(define_insn_and_split "div<mode>3"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+                (match_operand:VSF 2 "spu_reg_operand" "r")))
+   (clobber (match_scratch:VSF 3 "=&r"))
+   (clobber (match_scratch:VSF 4 "=&r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:VSF 0)
+       (div:VSF (match_dup:VSF 1)
+                (match_dup:VSF 2)))
+   (clobber (match_dup:VSF 3))
+   (clobber (match_dup:VSF 4))]
+  {
+    emit_insn(gen_frest_<mode>(operands[3], operands[2]));
+    emit_insn(gen_fi_<mode>(operands[3], operands[2], operands[3]));
+    emit_insn(gen_mul<mode>3(operands[4], operands[1], operands[3]));
+    emit_insn(gen_fnms_<mode>(operands[0], operands[4], operands[2], operands[1]));
+    emit_insn(gen_fma_<mode>(operands[0], operands[0], operands[3], operands[4]));
+    DONE;
+  })
+
+\f
+;; sqrt
+
+(define_insn_and_split "sqrtsf2"
+  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
+       (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
+   (clobber (match_scratch:SF 2 "=&r"))
+   (clobber (match_scratch:SF 3 "=&r"))
+   (clobber (match_scratch:SF 4 "=&r"))
+   (clobber (match_scratch:SF 5 "=&r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:SF 0)
+       (sqrt:SF (match_dup:SF 1)))
+   (clobber (match_dup:SF 2))
+   (clobber (match_dup:SF 3))
+   (clobber (match_dup:SF 4))
+   (clobber (match_dup:SF 5))]
+  {
+    emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
+    emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
+    emit_insn(gen_frsqest_sf(operands[2],operands[1]));
+    emit_insn(gen_fi_sf(operands[2],operands[1],operands[2]));
+    emit_insn(gen_mulsf3(operands[5],operands[2],operands[1]));
+    emit_insn(gen_mulsf3(operands[3],operands[5],operands[3]));
+    emit_insn(gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
+    emit_insn(gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
+    DONE;
+  })
+
+(define_insn "frest_<mode>"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
+  ""
+  "frest\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+(define_insn "frsqest_<mode>"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
+  ""
+  "frsqest\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+(define_insn "fi_<mode>"
+  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+       (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
+                   (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
+  ""
+  "fi\t%0,%1,%2"
+  [(set_attr "type" "fp7")])
+
+\f
+;; and
+
+(define_insn "and<mode>3"
+  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
+       (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
+                (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
+  ""
+  "@
+  and\t%0,%1,%2
+  and%j2i\t%0,%1,%J2")
+
+(define_insn "anddi3"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
+       (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
+               (match_operand:DI 2 "spu_logical_operand" "r,c")))]
+  ""
+  "@
+  and\t%0,%1,%2
+  and%k2i\t%0,%1,%K2")
+
+(define_insn "andti3"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+               (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
+  ""
+  "@
+  and\t%0,%1,%2
+  and%m2i\t%0,%1,%L2")
+
+(define_insn "andc_<mode>"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
+       (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
+                (match_operand:ALL 1 "spu_reg_operand" "r")))]
+  ""
+  "andc\t%0,%1,%2")
+
+(define_insn "nand_<mode>"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
+       (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
+                         (match_operand:ALL 1 "spu_reg_operand" "r"))))]
+  ""
+  "nand\t%0,%1,%2")
+
+\f
+;; ior
+
+(define_insn "ior<mode>3"
+  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
+       (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
+                (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
+  ""
+  "@
+  or\t%0,%1,%2
+  or%j2i\t%0,%1,%J2
+  iohl\t%0,%J2")
+
+(define_insn "iordi3"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
+       (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
+               (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
+  ""
+  "@
+  or\t%0,%1,%2
+  or%k2i\t%0,%1,%K2
+  iohl\t%0,%K2")
+
+(define_insn "iorti3"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
+       (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
+               (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
+  ""
+  "@
+  or\t%0,%1,%2
+  or%m2i\t%0,%1,%L2
+  iohl\t%0,%L2")
+
+(define_insn "orc_<mode>"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
+       (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
+                (match_operand:ALL 1 "spu_reg_operand" "r")))]
+  ""
+  "orc\t%0,%1,%2")
+
+(define_insn "nor_<mode>"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
+       (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
+                         (match_operand:ALL 2 "spu_reg_operand" "r"))))]
+  ""
+  "nor\t%0,%1,%2")
+\f
+;; xor
+
+(define_insn "xor<mode>3"
+  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
+       (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
+                (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
+  ""
+  "@
+  xor\t%0,%1,%2
+  xor%j2i\t%0,%1,%S2")
+
+(define_insn "xordi3"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
+       (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
+               (match_operand:DI 2 "spu_logical_operand" "r,c")))]
+  ""
+  "@
+  xor\t%0,%1,%2
+  xor%k2i\t%0,%1,%K2")
+
+(define_insn "xorti3"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+               (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
+  ""
+  "@
+  xor\t%0,%1,%2
+  xor%m2i\t%0,%1,%L2")
+
+(define_insn "eqv_<mode>"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
+       (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
+                         (match_operand:ALL 2 "spu_reg_operand" "r"))))]
+  ""
+  "eqv\t%0,%1,%2")
+\f
+;; one_cmpl
+
+(define_insn "one_cmpl<mode>2"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
+       (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
+  ""
+  "nor\t%0,%1,%1")
+
+\f
+;; selb
+
+(define_expand "selb"
+  [(set (match_operand 0 "spu_reg_operand" "")
+       (unspec [(match_operand 1 "spu_reg_operand" "")
+                (match_operand 2 "spu_reg_operand" "")
+                (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
+  ""
+  {
+    rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
+    PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
+    emit_insn (s);
+    DONE;
+  })
+
+;; This could be defined as a combination of logical operations, but at
+;; one time it caused a crash due to recursive expansion of rtl during CSE.
+(define_insn "_selb"
+  [(set (match_operand 0 "spu_reg_operand" "=r")
+       (unspec [(match_operand 1 "spu_reg_operand" "r")
+                (match_operand 2 "spu_reg_operand" "r")
+                (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
+  "GET_MODE(operands[0]) == GET_MODE(operands[1]) 
+   && GET_MODE(operands[1]) == GET_MODE(operands[2])"
+  "selb\t%0,%1,%2,%3")
+
+\f
+;; Misc. byte/bit operations
+;; clz/ctz/ffs/popcount/parity
+;; cntb/sumb
+
+(define_insn "clz<mode>2"
+  [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
+       (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
+  ""
+  "clz\t%0,%1")
+
+(define_expand "ctz<mode>2"
+  [(set (match_dup 2)
+       (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
+   (set (match_dup 3) (and:VSI (match_dup 1)
+                              (match_dup 2)))
+   (set (match_dup 4) (clz:VSI (match_dup 3)))
+   (set (match_operand:VSI 0 "spu_reg_operand" "")
+       (minus:VSI (match_dup 5) (match_dup 4)))]
+  ""
+  {
+     operands[2] = gen_reg_rtx (<MODE>mode);
+     operands[3] = gen_reg_rtx (<MODE>mode);
+     operands[4] = gen_reg_rtx (<MODE>mode);
+     operands[5] = spu_const(<MODE>mode, 31);
+  })
+
+(define_expand "ffs<mode>2"
+  [(set (match_dup 2)
+       (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
+   (set (match_dup 3) (and:VSI (match_dup 1)
+                              (match_dup 2)))
+   (set (match_dup 4) (clz:VSI (match_dup 3)))
+   (set (match_operand:VSI 0 "spu_reg_operand" "")
+       (minus:VSI (match_dup 5) (match_dup 4)))]
+  ""
+  {
+     operands[2] = gen_reg_rtx (<MODE>mode);
+     operands[3] = gen_reg_rtx (<MODE>mode);
+     operands[4] = gen_reg_rtx (<MODE>mode);
+     operands[5] = spu_const(<MODE>mode, 32);
+  })
+
+(define_expand "popcountsi2"
+  [(set (match_dup 2)
+       (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
+                    UNSPEC_CNTB))
+   (set (match_dup 3)
+       (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
+   (set (match_operand:SI 0 "spu_reg_operand" "")
+       (sign_extend:SI (match_dup 3)))]
+  ""
+  {
+    operands[2] = gen_reg_rtx (SImode);
+    operands[3] = gen_reg_rtx (HImode);
+  })
+
+(define_expand "paritysi2"
+  [(set (match_operand:SI 0 "spu_reg_operand" "")
+       (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
+  ""
+  {
+    operands[2] = gen_reg_rtx (SImode);
+    emit_insn (gen_popcountsi2(operands[2], operands[1]));
+    emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
+    DONE;
+  })
+
+(define_insn "cntb_si"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
+                   UNSPEC_CNTB))]
+  ""
+  "cntb\t%0,%1"
+  [(set_attr "type" "fxb")])
+
+(define_insn "cntb_v16qi"
+  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
+        (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
+                      UNSPEC_CNTB))]
+  ""
+  "cntb\t%0,%1"
+  [(set_attr "type" "fxb")])
+
+(define_insn "sumb_si"
+  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
+        (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
+  ""
+  "sumb\t%0,%1,%1"
+  [(set_attr "type" "fxb")])
+
+\f
+;; ashl
+
+(define_insn "ashl<mode>3"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
+                    (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
+  ""
+  "@
+  shl<bh>\t%0,%1,%2
+  shl<bh>i\t%0,%1,%2"
+  [(set_attr "type" "fx3")])
+
+(define_insn_and_split "ashldi3"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
+       (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
+                  (match_operand:SI 2 "spu_shift_operand" "r,I")))
+   (clobber (match_scratch:SI 3 "=&r,X"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:DI 0)
+       (ashift:DI (match_dup:DI 1)
+                  (match_dup:SI 2)))]
+  {
+    rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
+    rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
+    rtx op2 = operands[2];
+    rtx op3 = operands[3];
+
+    if (GET_CODE (operands[2]) == REG)
+      {
+       emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
+       emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
+       emit_insn (gen_shlqbybi_ti (op0, op0, op3));
+       emit_insn (gen_shlqbi_ti (op0, op0, op3));
+      }
+    else
+      {
+       HOST_WIDE_INT val = INTVAL (operands[2]);
+       emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
+       emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
+       if (val % 8)
+         emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
+      }
+    DONE;
+  })
+
+(define_expand "ashlti3"
+  [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
+                  (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
+                             (match_operand:SI 2 "spu_nonmem_operand" "")))
+             (clobber (match_dup:TI 3))])]
+  ""
+  "if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      emit_insn(gen_ashlti3_imm(operands[0], operands[1], operands[2]));
+      DONE;
+    }
+   operands[3] = gen_reg_rtx (TImode);")
+
+(define_insn_and_split "ashlti3_imm"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+                  (match_operand:SI 2 "immediate_operand" "O,P")))]
+  ""
+  "@
+   shlqbyi\t%0,%1,%2/8
+   shlqbii\t%0,%1,%2"
+  "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
+  [(set (match_dup:TI 0)
+       (ashift:TI (match_dup:TI 1)
+                  (match_dup:SI 3)))
+   (set (match_dup:TI 0)
+       (ashift:TI (match_dup:TI 0)
+                  (match_dup:SI 4)))]
+  {
+    HOST_WIDE_INT val = INTVAL(operands[2]);
+    operands[3] = GEN_INT (val&7);
+    operands[4] = GEN_INT (val&0x78);
+  }
+  [(set_attr "type" "shuf,shuf")])
+
+(define_insn_and_split "ashlti3_reg"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+       (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
+                  (match_operand:SI 2 "spu_reg_operand" "r")))
+   (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
+  ""
+  "#"
+  ""
+  [(set (match_dup:TI 3)
+       (ashift:TI (match_dup:TI 1)
+                  (and:SI (match_dup:SI 2)
+                          (const_int 7))))
+   (set (match_dup:TI 0)
+       (ashift:TI (match_dup:TI 3)
+                  (and:SI (match_dup:SI 2)
+                          (const_int -8))))]
+  "")
+
+(define_insn "shlqbybi_ti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+                  (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
+                          (const_int -8))))]
+  ""
+  "@
+   shlqbybi\t%0,%1,%2
+   shlqbyi\t%0,%1,%2/8"
+  [(set_attr "type" "shuf,shuf")])
+
+(define_insn "shlqbi_ti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+                  (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
+                          (const_int 7))))]
+  ""
+  "@
+   shlqbi\t%0,%1,%2
+   shlqbii\t%0,%1,%2"
+  [(set_attr "type" "shuf,shuf")])
+
+(define_insn "shlqby_ti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+                  (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
+                           (const_int 8))))]
+  ""
+  "@
+   shlqby\t%0,%1,%2
+   shlqbyi\t%0,%1,%2"
+  [(set_attr "type" "shuf,shuf")])
+
+\f
+;; lshr
+
+(define_insn_and_split "lshr<mode>3"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
+                      (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
+   (clobber (match_scratch:VHSI 3 "=&r,X"))]
+  ""
+  "@
+   #
+   rot<bh>mi\t%0,%1,%N2"
+  "reload_completed && GET_CODE (operands[2]) == REG"
+  [(set (match_dup:VHSI 3)
+       (neg:VHSI (match_dup:VHSI 2)))
+   (set (match_dup:VHSI 0)
+       (lshiftrt:VHSI (match_dup:VHSI 1)
+                      (neg:VHSI (match_dup:VHSI 3))))]
+  ""
+  [(set_attr "type" "*,fx3")])
+  
+
+(define_insn "rotm_<mode>"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
+                      (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
+  ""
+  "@
+   rot<bh>m\t%0,%1,%2
+   rot<bh>mi\t%0,%1,%2"
+  [(set_attr "type" "fx3")])
+(define_expand "lshr<mode>3"
+  [(parallel [(set (match_operand:DTI 0 "spu_reg_operand" "")
+                  (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "")
+                                (match_operand:SI 2 "spu_nonmem_operand" "")))
+             (clobber (match_dup:DTI 3))
+             (clobber (match_dup:SI 4))
+             (clobber (match_dup:SI 5))])]
+  ""
+  "if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      emit_insn(gen_lshr<mode>3_imm(operands[0], operands[1], operands[2]));
+      DONE;
+    }
+   operands[3] = gen_reg_rtx (<MODE>mode);
+   operands[4] = gen_reg_rtx (SImode);
+   operands[5] = gen_reg_rtx (SImode);")
+
+(define_insn_and_split "lshr<mode>3_imm"
+  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
+       (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
+                     (match_operand:SI 2 "immediate_operand" "O,P")))]
+  ""
+  "@
+   rotqmbyi\t%0,%1,%N2/8
+   rotqmbii\t%0,%1,%N2"
+  "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
+  [(set (match_dup:DTI 0)
+       (lshiftrt:DTI (match_dup:DTI 1)
+                     (match_dup:SI 4)))
+   (set (match_dup:DTI 0)
+       (lshiftrt:DTI (match_dup:DTI 0)
+                     (match_dup:SI 5)))]
+  {
+    HOST_WIDE_INT val = INTVAL(operands[2]);
+    operands[4] = GEN_INT (val&7);
+    operands[5] = GEN_INT (val&0x78);
+  }
+  [(set_attr "type" "shuf,shuf")])
+
+(define_insn_and_split "lshr<mode>3_reg"
+  [(set (match_operand:DTI 0 "spu_reg_operand" "=r")
+       (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r")
+                     (match_operand:SI 2 "spu_reg_operand" "r")))
+   (clobber (match_operand:DTI 3 "spu_reg_operand" "=&r"))
+   (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
+   (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))]
+  ""
+  "#"
+  ""
+  [(set (match_dup:DTI 3)
+       (lshiftrt:DTI (match_dup:DTI 1)
+                    (and:SI (neg:SI (match_dup:SI 4))
+                            (const_int 7))))
+   (set (match_dup:DTI 0)
+       (lshiftrt:DTI (match_dup:DTI 3)
+                    (and:SI (neg:SI (match_dup:SI 5))
+                            (const_int -8))))]
+  {
+    emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2]));
+    emit_insn(gen_subsi3(operands[5], GEN_INT(7), operands[2]));
+  })
+
+(define_insn "rotqmbybi_<mode>"
+  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
+       (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
+                     (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
+                             (const_int -8))))]
+  ""
+  "@
+   rotqmbybi\t%0,%1,%2
+   rotqmbyi\t%0,%1,%2/8"
+  [(set_attr "type" "shuf")])
+
+(define_insn "rotqmbi_<mode>"
+  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
+       (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
+                     (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
+                             (const_int 7))))]
+  ""
+  "@
+   rotqmbi\t%0,%1,%2
+   rotqmbii\t%0,%1,%2"
+  [(set_attr "type" "shuf")])
+
+(define_insn "rotqmby_<mode>"
+  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
+       (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
+                     (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
+                              (const_int 8))))]
+  ""
+  "@
+   rotqmby\t%0,%1,%2
+   rotqmbyi\t%0,%1,%2"
+  [(set_attr "type" "shuf")])
+
+\f
+;; ashr
+
+(define_insn_and_split "ashr<mode>3"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
+                      (match_operand:VHSI 2 "spu_shift_operand" "r,W")))
+   (clobber (match_scratch:VHSI 3 "=&r,X"))]
+  ""
+  "@
+   #
+   rotma<bh>i\t%0,%1,%N2"
+  "reload_completed && GET_CODE (operands[2]) == REG"
+  [(set (match_dup:VHSI 3)
+       (neg:VHSI (match_dup:VHSI 2)))
+   (set (match_dup:VHSI 0)
+       (ashiftrt:VHSI (match_dup:VHSI 1)
+                      (neg:VHSI (match_dup:VHSI 3))))]
+  ""
+  [(set_attr "type" "*,fx3")])
+  
+
+(define_insn "rotma_<mode>"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
+                      (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))]
+  ""
+  "@
+   rotma<bh>\t%0,%1,%2
+   rotma<bh>i\t%0,%1,%2"
+  [(set_attr "type" "fx3")])
+(define_insn_and_split "ashrdi3"
+  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
+        (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
+                     (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
+   (clobber (match_scratch:TI 3 "=&r,&r"))
+   (clobber (match_scratch:TI 4 "=&r,&r"))
+   (clobber (match_scratch:SI 5 "=&r,&r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:DI 0)
+        (ashiftrt:DI (match_dup:DI 1)
+                     (match_dup:SI 2)))]
+  {
+    rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
+    rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
+    rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
+    rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
+    rtx op2 = operands[2];
+    rtx op3 = operands[3];
+    rtx op4 = operands[4];
+    rtx op5 = operands[5];
+
+    if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
+      {
+       rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
+       emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
+       emit_insn (gen_spu_fsm (op0v, op0s));
+      }
+    else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
+      {
+       rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
+       HOST_WIDE_INT val = INTVAL (op2);
+       emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
+       emit_insn (gen_spu_xswd (op0d, op0v));
+        if (val > 32)
+         emit_insn (gen_ashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
+      }
+    else
+      {
+       rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
+       unsigned char arr[16] = {
+         0xff, 0xff, 0xff, 0xff,
+         0xff, 0xff, 0xff, 0xff,
+         0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00
+       };
+
+       emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
+       emit_move_insn (op4, array_to_constant (TImode, arr));
+       emit_insn (gen_spu_fsm (op3v, op5));
+
+       if (GET_CODE (operands[2]) == REG)
+         {
+           emit_insn (gen_selb (op4, op3, op1, op4));
+           emit_insn (gen_negsi2 (op5, op2));
+           emit_insn (gen_rotqbybi_ti (op0, op4, op5));
+           emit_insn (gen_rotqbi_ti (op0, op0, op5));
+         }
+       else
+         {
+           HOST_WIDE_INT val = -INTVAL (op2);
+           emit_insn (gen_selb (op0, op3, op1, op4));
+           if ((val - 7) / 8)
+             emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
+           if (val % 8)
+             emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
+         }
+      }
+    DONE;
+  })
+
+
+(define_expand "ashrti3"
+  [(set (match_operand:TI 0 "spu_reg_operand" "")
+       (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "")
+                    (match_operand:SI 2 "spu_nonmem_operand" "")))]
+  ""
+  {
+    rtx sign_shift = gen_reg_rtx (SImode);
+    rtx sign_mask = gen_reg_rtx (TImode);
+    rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
+    rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
+    rtx t = gen_reg_rtx (TImode);
+    emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
+    emit_insn (gen_ashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
+    emit_insn (gen_fsm_ti (sign_mask, sign_mask));
+    emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
+    emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
+    emit_insn (gen_iorti3 (operands[0], t, sign_mask));
+    DONE;
+  })
+
+;; fsm is used after rotam to replicate the sign across the whole register.
+(define_insn "fsm_ti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+       (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
+  ""
+  "fsm\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+\f
+;; rotl
+
+(define_insn "rotl<mode>3"
+  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
+       (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
+                    (match_operand:VHSI 2 "spu_shift_operand" "r,W")))]
+  ""
+  "@
+  rot<bh>\t%0,%1,%2
+  rot<bh>i\t%0,%1,%2"
+  [(set_attr "type" "fx3")])
+
+(define_insn "rotlti3"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
+       (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
+                  (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
+  ""
+  "@
+  rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
+  rotqbyi\t%0,%1,%2/8
+  rotqbii\t%0,%1,%2
+  rotqbyi\t%0,%1,%2/8\;rotqbii\t%0,%0,%2%%8"
+  [(set_attr "length" "8,4,4,8")
+   (set_attr "type" "multi1,shuf,shuf,multi1")])
+
+(define_insn "rotqbybi_ti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+                  (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
+                          (const_int -8))))]
+  ""
+  "@
+  rotqbybi\t%0,%1,%2
+  rotqbyi\t%0,%1,%2/8"
+  [(set_attr "type" "shuf,shuf")])
+
+(define_insn "rotqby_ti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+                  (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
+                           (const_int 8))))]
+  ""
+  "@
+  rotqby\t%0,%1,%2
+  rotqbyi\t%0,%1,%2"
+  [(set_attr "type" "shuf,shuf")])
+
+(define_insn "rotqbi_ti"
+  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+       (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+                  (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
+                          (const_int 7))))]
+  ""
+  "@
+  rotqbi\t%0,%1,%2
+  rotqbii\t%0,%1,%2%%8"
+  [(set_attr "type" "shuf,shuf")])
+
+\f
+;; struct extract/insert
+;; We have to handle mem's because GCC will generate invalid SUBREG's
+;; if it handles them.  We generate better code anyway.
+
+(define_expand "extv"
+  [(set (match_operand 0 "register_operand" "")
+       (sign_extract (match_operand 1 "register_operand" "")
+                     (match_operand:SI 2 "const_int_operand" "")
+                     (match_operand:SI 3 "const_int_operand" "")))]
+  ""
+  { spu_expand_extv(operands, 0); DONE; })
+
+(define_expand "extzv"
+  [(set (match_operand 0 "register_operand" "")
+       (zero_extract (match_operand 1 "register_operand" "")
+                        (match_operand:SI 2 "const_int_operand" "")
+                        (match_operand:SI 3 "const_int_operand" "")))]
+  ""
+  { spu_expand_extv(operands, 1); DONE; })
+
+(define_expand "insv"
+  [(set (zero_extract (match_operand 0 "register_operand" "")
+                     (match_operand:SI 1 "const_int_operand" "")
+                     (match_operand:SI 2 "const_int_operand" ""))
+       (match_operand 3 "nonmemory_operand" ""))]
+  ""
+  { spu_expand_insv(operands); DONE; })
+
+\f
+;; String/block move insn.
+;; Argument 0 is the destination
+;; Argument 1 is the source
+;; Argument 2 is the length
+;; Argument 3 is the alignment
+
+(define_expand "movstrsi"
+  [(parallel [(set (match_operand:BLK 0 "" "")
+                  (match_operand:BLK 1 "" ""))
+             (use (match_operand:SI 2 "" ""))
+             (use (match_operand:SI 3 "" ""))])]
+  ""
+  "
+  {
+    if (spu_expand_block_move (operands))
+      DONE;
+    else
+      FAIL;
+  }")
+
+\f
+;; jump
+
+(define_insn "indirect_jump"
+  [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
+  ""
+  "bi\t%0"
+  [(set_attr "type" "br")])
+
+(define_insn "jump"
+  [(set (pc)
+       (label_ref (match_operand 0 "" "")))]
+  ""
+  "br\t%0"
+  [(set_attr "type" "br")])
+
+\f
+;; return
+
+;; This will be used for leaf functions, that don't save any regs and
+;; don't have locals on stack, maybe... that is for functions that
+;; don't change $sp and don't need to save $lr. 
+(define_expand "return"
+    [(return)]
+  "direct_return()"
+  "")
+
+;; used in spu_expand_epilogue to generate return from a function and
+;; explicitly set use of $lr.
+
+(define_insn "_return"
+  [(return)]
+  ""
+  "bi\t$lr"
+  [(set_attr "type" "br")])
+
+
+\f
+;; ceq
+
+(define_insn "ceq_<mode>"
+  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
+       (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
+                (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
+  ""
+  "@
+  ceq<bh>\t%0,%1,%2
+  ceq<bh>i\t%0,%1,%2")
+
+(define_insn_and_split "ceq_di"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (eq:SI (match_operand:DI 1 "register_operand" "r")
+              (match_operand:DI 2 "register_operand" "r")))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:SI 0)
+        (eq:SI (match_dup:DI 1)
+              (match_dup:DI 2)))]
+  {
+    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
+    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
+    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
+    emit_insn (gen_ceq_v4si (op0, op1, op2));
+    emit_insn (gen_spu_gb (op0, op0));
+    emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
+    DONE;
+  })
+
+
+;; We provide the TI compares for completeness and because some parts of
+;; gcc/libgcc use them, even though user code might never see it.
+(define_insn "ceq_ti"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
+              (match_operand:TI 2 "spu_reg_operand" "r")))]
+  ""
+  "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
+  [(set_attr "type" "multi0")
+   (set_attr "length" "12")])
+
+(define_insn "ceq_<mode>"
+  [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
+       (eq:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
+                 (match_operand:VSF 2 "spu_reg_operand" "r")))]
+  ""
+  "fceq\t%0,%1,%2")
+
+(define_insn "cmeq_<mode>"
+  [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
+       (eq:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
+                 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
+  ""
+  "fcmeq\t%0,%1,%2")
+
+(define_insn "ceq_vec"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (eq:SI (match_operand 1 "spu_reg_operand" "r")
+              (match_operand 2 "spu_reg_operand" "r")))]
+  "VECTOR_MODE_P(GET_MODE(operands[1]))
+   && GET_MODE(operands[1]) == GET_MODE(operands[2])"
+  "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
+  [(set_attr "length" "12")])
+
+\f
+;; cgt
+
+(define_insn "cgt_<mode>"
+  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
+       (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
+                 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
+  ""
+  "@
+  cgt<bh>\t%0,%1,%2
+  cgt<bh>i\t%0,%1,%2")
+
+(define_insn "cgt_di_m1" 
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
+              (const_int -1)))]
+  ""
+  "cgti\t%0,%1,-1")
+
+(define_insn_and_split "cgt_di" 
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
+              (match_operand:DI 2 "spu_reg_operand" "r")))
+   (clobber (match_scratch:V4SI 3 "=&r"))
+   (clobber (match_scratch:V4SI 4 "=&r"))
+   (clobber (match_scratch:V4SI 5 "=&r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:SI 0)
+        (gt:SI (match_dup:DI 1)
+              (match_dup:DI 2)))]
+  {
+    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
+    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
+    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
+    rtx op3 = operands[3];
+    rtx op4 = operands[4];
+    rtx op5 = operands[5];
+    rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
+    emit_insn (gen_clgt_v4si (op3, op1, op2));
+    emit_insn (gen_ceq_v4si (op4, op1, op2));
+    emit_insn (gen_cgt_v4si (op5, op1, op2));
+    emit_insn (gen_spu_xswd (op3d, op3));
+    emit_insn (gen_selb (op0, op5, op3, op4));
+    DONE;
+  })
+
+(define_insn "cgt_ti"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
+              (match_operand:TI 2 "spu_reg_operand" "r")))
+   (clobber (match_scratch:V4SI 3 "=&r"))
+   (clobber (match_scratch:V4SI 4 "=&r"))
+   (clobber (match_scratch:V4SI 5 "=&r"))]
+  ""
+  "clgt\t%4,%1,%2\;\
+ceq\t%3,%1,%2\;\
+cgt\t%5,%1,%2\;\
+shlqbyi\t%0,%4,4\;\
+selb\t%0,%4,%0,%3\;\
+shlqbyi\t%0,%0,4\;\
+selb\t%0,%4,%0,%3\;\
+shlqbyi\t%0,%0,4\;\
+selb\t%0,%5,%0,%3"
+  [(set_attr "type" "multi0")
+   (set_attr "length" "36")])
+
+(define_insn "cgt_<mode>"
+  [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
+       (gt:<f2i> (match_operand:VSF 1 "spu_reg_operand" "r")
+                 (match_operand:VSF 2 "spu_reg_operand" "r")))]
+  ""
+  "fcgt\t%0,%1,%2")
+
+(define_insn "cmgt_<mode>"
+  [(set (match_operand:<f2i> 0 "spu_reg_operand" "=r")
+       (gt:<f2i> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
+                 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
+  ""
+  "fcmgt\t%0,%1,%2")
+
+\f
+;; clgt
+
+(define_insn "clgt_<mode>"
+  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
+       (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
+                  (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
+  ""
+  "@
+  clgt<bh>\t%0,%1,%2
+  clgt<bh>i\t%0,%1,%2")
+
+(define_insn_and_split "clgt_di" 
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
+               (match_operand:DI 2 "spu_reg_operand" "r")))
+   (clobber (match_scratch:V4SI 3 "=&r"))
+   (clobber (match_scratch:V4SI 4 "=&r"))
+   (clobber (match_scratch:V4SI 5 "=&r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:SI 0)
+        (gtu:SI (match_dup:DI 1)
+               (match_dup:DI 2)))]
+  {
+    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
+    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
+    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
+    rtx op3 = operands[3];
+    rtx op4 = operands[4];
+    rtx op5 = operands[5];
+    rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
+    emit_insn (gen_clgt_v4si (op3, op1, op2));
+    emit_insn (gen_ceq_v4si (op4, op1, op2));
+    emit_insn (gen_spu_xswd (op5d, op3));
+    emit_insn (gen_selb (op0, op3, op5, op4));
+    DONE;
+  })
+
+(define_insn "clgt_ti"
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
+              (match_operand:TI 2 "spu_reg_operand" "r")))
+   (clobber (match_scratch:V4SI 3 "=&r"))
+   (clobber (match_scratch:V4SI 4 "=&r"))]
+  ""
+  "ceq\t%3,%1,%2\;\
+clgt\t%4,%1,%2\;\
+shlqbyi\t%0,%4,4\;\
+selb\t%0,%4,%0,%3\;\
+shlqbyi\t%0,%0,4\;\
+selb\t%0,%4,%0,%3\;\
+shlqbyi\t%0,%0,4\;\
+selb\t%0,%4,%0,%3"
+  [(set_attr "type" "multi0")
+   (set_attr "length" "32")])
+
+\f
+;; branches
+
+(define_insn ""
+  [(set (pc)
+       (if_then_else (match_operator 1 "branch_comparison_operator"
+                                     [(match_operand 2
+                                                     "spu_reg_operand" "r")
+                                      (const_int 0)])
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "br%b2%b1z\t%2,%0"
+  [(set_attr "type" "br")])
+
+(define_insn ""
+  [(set (pc)
+       (if_then_else (match_operator 0 "branch_comparison_operator"
+                                     [(match_operand 1
+                                                     "spu_reg_operand" "r")
+                                      (const_int 0)])
+                     (return)
+                     (pc)))]
+  "direct_return ()"
+  "bi%b1%b0z\t%1,$lr"
+  [(set_attr "type" "br")])
+
+(define_insn ""
+  [(set (pc)
+       (if_then_else (match_operator 1 "branch_comparison_operator"
+                                     [(match_operand 2
+                                                     "spu_reg_operand" "r")
+                                      (const_int 0)])
+                     (pc)
+                     (label_ref (match_operand 0 "" ""))))]
+  ""
+  "br%b2%b1z\t%2,%0"
+  [(set_attr "type" "br")])
+
+(define_insn ""
+  [(set (pc)
+       (if_then_else (match_operator 0 "branch_comparison_operator"
+                                     [(match_operand 1
+                                                     "spu_reg_operand" "r")
+                                      (const_int 0)])
+                     (pc)
+                     (return)))]
+  "direct_return ()"
+  "bi%b1%b0z\t%1,$lr"
+  [(set_attr "type" "br")])
+
+\f
+;; Compare insns are next.  Note that the spu has two types of compares,
+;; signed & unsigned, and one type of branch.
+;;
+;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
+;; insns, and branches.  We store the operands of compares until we see
+;; how it is used.
+
+(define_expand "cmp<mode>"
+  [(set (cc0)
+       (compare (match_operand:VINT 0 "spu_reg_operand" "")
+                (match_operand:VINT 1 "spu_nonmem_operand" "")))]
+  ""
+  {
+    spu_compare_op0 = operands[0];
+    spu_compare_op1 = operands[1];
+    DONE;
+  })
+
+(define_expand "cmp<mode>"
+  [(set (cc0)
+       (compare (match_operand:VSF 0 "spu_reg_operand" "")
+                (match_operand:VSF 1 "spu_nonmem_operand" "")))]
+  ""
+  {
+    spu_compare_op0 = operands[0];
+    spu_compare_op1 = operands[1];
+    DONE;
+  })
+
+\f
+;; branch on condition
+
+(define_expand "beq"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, EQ, operands); DONE; })
+
+(define_expand "bne"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, NE, operands); DONE; })
+
+(define_expand "bge"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, GE, operands); DONE; })
+
+(define_expand "bgt"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, GT, operands); DONE; })
+
+(define_expand "ble"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, LE, operands); DONE; })
+
+(define_expand "blt"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, LT, operands); DONE; })
+
+(define_expand "bgeu"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, GEU, operands); DONE; })
+
+(define_expand "bgtu"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, GTU, operands); DONE; })
+
+(define_expand "bleu"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, LEU, operands); DONE; })
+
+(define_expand "bltu"
+  [(use (match_operand 0 "" ""))]
+  ""
+  { spu_emit_branch_or_set (0, LTU, operands); DONE; })
+
+\f
+;; set on condition
+
+(define_expand "seq"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, EQ, operands); DONE; })
+
+(define_expand "sne"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, NE, operands); DONE; })
+
+(define_expand "sgt"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, GT, operands); DONE; })
+
+(define_expand "slt"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, LT, operands); DONE; })
+
+(define_expand "sge"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, GE, operands); DONE; })
+
+(define_expand "sle"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, LE, operands); DONE; })
+
+(define_expand "sgtu"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, GTU, operands); DONE; })
+
+(define_expand "sltu"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, LTU, operands); DONE; })
+
+(define_expand "sgeu"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, GEU, operands); DONE; })
+
+(define_expand "sleu"
+  [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+  ""
+  { spu_emit_branch_or_set (1, LEU, operands); DONE; })
+
+\f
+;; conditional move
+
+;; Define this first one so HAVE_conditional_move is defined.
+(define_insn "movcc_dummy"
+  [(set (match_operand 0 "" "")
+       (if_then_else (match_operand 1 "" "")
+                    (match_operand 2 "" "")
+                    (match_operand 3 "" "")))]
+  "!operands[0]"
+  "")
+
+(define_expand "mov<mode>cc"
+  [(set (match_operand:ALL 0 "spu_reg_operand" "")
+       (if_then_else:ALL (match_operand 1 "comparison_operator" "")
+                     (match_operand:ALL 2 "spu_reg_operand" "")
+                     (match_operand:ALL 3 "spu_reg_operand" "")))]
+  ""
+  {
+    spu_emit_branch_or_set(2, GET_CODE(operands[1]), operands);
+    DONE;
+  })
+
+;; This pattern is used when the result of a compare is not large
+;; enough to use in a selb when expanding conditional moves.
+(define_insn "extend_compare"
+  [(set (match_operand 0 "spu_reg_operand" "=r")
+       (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
+  "operands"
+  "fsm\t%0,%1"
+  [(set_attr "type" "shuf")])
+
+\f
+;; case
+
+;; operand 0 is index
+;; operand 1 is the minimum bound
+;; operand 2 is the maximum bound - minimum bound + 1
+;; operand 3 is CODE_LABEL for the table;
+;; operand 4 is the CODE_LABEL to go to if index out of range.
+(define_expand "casesi"
+  [(match_operand:SI 0 "spu_reg_operand" "")
+   (match_operand:SI 1 "immediate_operand" "")
+   (match_operand:SI 2 "immediate_operand" "")
+   (match_operand 3 "" "")
+   (match_operand 4 "" "")]
+  ""
+  {
+    rtx table = gen_reg_rtx (SImode);
+    rtx index = gen_reg_rtx (SImode);
+    rtx sindex = gen_reg_rtx (SImode);
+    rtx addr = gen_reg_rtx (Pmode);
+
+    emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
+
+    emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
+    emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
+    emit_move_insn (addr, gen_rtx_MEM (SImode,
+                                      gen_rtx_PLUS (SImode, table, sindex)));
+    if (flag_pic)
+      emit_insn (gen_addsi3 (addr, addr, table));
+
+    emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
+    emit_jump_insn (gen_tablejump (addr, operands[3]));
+    DONE;
+  })
+
+(define_insn "tablejump"
+  [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
+   (use (label_ref (match_operand 1 "" "")))]
+  ""
+  "bi\t%0"
+  [(set_attr "type" "br")])
+
+\f
+;; call
+
+;; Note that operand 1 is total size of args, in bytes,
+;; and what the call insn wants is the number of words.
+(define_expand "sibcall"
+  [(parallel
+    [(call (match_operand:QI 0 "call_operand" "")
+          (match_operand:QI 1 "" ""))
+     (use (reg:SI 0))])]
+  ""
+  {
+    if (! call_operand (operands[0], QImode))
+      XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
+  })
+
+(define_insn "_sibcall"
+  [(parallel
+    [(call (match_operand:QI 0 "call_operand" "R,S")
+          (match_operand:QI 1 "" "i,i"))
+     (use (reg:SI 0))])]
+  "SIBLING_CALL_P(insn)"
+  "@
+   bi\t%i0
+   br\t%0"
+   [(set_attr "type" "br,br")])
+
+(define_expand "sibcall_value"
+  [(parallel
+    [(set (match_operand 0 "" "")
+         (call (match_operand:QI 1 "call_operand" "")
+               (match_operand:QI 2 "" "")))
+     (use (reg:SI 0))])]
+  ""
+  {
+    if (! call_operand (operands[1], QImode))
+      XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
+  })
+
+(define_insn "_sibcall_value"
+  [(parallel
+    [(set (match_operand 0 "" "")
+         (call (match_operand:QI 1 "call_operand" "R,S")
+               (match_operand:QI 2 "" "i,i")))
+     (use (reg:SI 0))])]
+  "SIBLING_CALL_P(insn)"
+  "@
+   bi\t%i1
+   br\t%1"
+   [(set_attr "type" "br,br")])
+
+;; Note that operand 1 is total size of args, in bytes,
+;; and what the call insn wants is the number of words.
+(define_expand "call"
+  [(parallel
+    [(call (match_operand:QI 0 "call_operand" "")
+          (match_operand:QI 1 "" ""))
+     (clobber (reg:SI 0))
+     (clobber (reg:SI 130))])]
+  ""
+  {
+    if (! call_operand (operands[0], QImode))
+      XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
+  })
+
+(define_insn "_call"
+  [(parallel
+    [(call (match_operand:QI 0 "call_operand" "R,S,T")
+          (match_operand:QI 1 "" "i,i,i"))
+     (clobber (reg:SI 0))
+     (clobber (reg:SI 130))])]
+  ""
+  "@
+   bisl\t$lr,%i0
+   brsl\t$lr,%0
+   brasl\t$lr,%0"
+   [(set_attr "type" "br")])
+
+(define_expand "call_value"
+  [(parallel
+    [(set (match_operand 0 "" "")
+         (call (match_operand:QI 1 "call_operand" "")
+               (match_operand:QI 2 "" "")))
+     (clobber (reg:SI 0))
+     (clobber (reg:SI 130))])]
+  ""
+  {
+    if (! call_operand (operands[1], QImode))
+      XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
+  })
+
+(define_insn "_call_value"
+  [(parallel
+    [(set (match_operand 0 "" "")
+         (call (match_operand:QI 1 "call_operand" "R,S,T")
+               (match_operand:QI 2 "" "i,i,i")))
+     (clobber (reg:SI 0))
+     (clobber (reg:SI 130))])]
+  ""
+  "@
+   bisl\t$lr,%i1
+   brsl\t$lr,%1
+   brasl\t$lr,%1"
+   [(set_attr "type" "br")])
+
+(define_expand "untyped_call"
+  [(parallel [(call (match_operand 0 "" "")
+                   (const_int 0))
+             (match_operand 1 "" "")
+             (match_operand 2 "" "")])]
+  ""
+  {
+    int i;
+    rtx reg = gen_rtx_REG (TImode, 3);
+
+    /* We need to use call_value so the return value registers don't get
+     * clobbered. */
+    emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
+
+    for (i = 0; i < XVECLEN (operands[2], 0); i++)
+      {
+       rtx set = XVECEXP (operands[2], 0, i);
+       emit_move_insn (SET_DEST (set), SET_SRC (set));
+      }
+
+    /* The optimizer does not know that the call sets the function value
+       registers we stored in the result block.  We avoid problems by
+       claiming that all hard registers are used and clobbered at this
+       point.  */
+    emit_insn (gen_blockage ());
+
+    DONE;
+  })
+
+\f
+;; Patterns used for splitting and combining.
+
+\f
+;; Function prologue and epilogue.
+
+(define_expand "prologue"
+  [(const_int 1)]
+  ""
+  { spu_expand_prologue (); DONE; })
+
+;; "blockage" is only emited in epilogue.  This is what it took to
+;; make "basic block reordering" work with the insns sequence
+;; generated by the spu_expand_epilogue (taken from mips.md)
+
+(define_insn "blockage"
+  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
+  ""
+  ""
+  [(set_attr "length" "0")])
+
+(define_expand "epilogue"
+  [(const_int 2)]
+  ""
+  { spu_expand_epilogue (false); DONE; })
+
+(define_expand "sibcall_epilogue"
+  [(const_int 2)]
+  ""
+  { spu_expand_epilogue (true); DONE; })
+
+\f
+;; stack manipulations
+
+;; An insn to allocate new stack space for dynamic use (e.g., alloca).
+;; We move the back-chain and decrement the stack pointer.
+(define_expand "allocate_stack"
+  [(set (match_operand 0 "spu_reg_operand" "")
+       (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
+   (set (reg 1)
+       (minus (reg 1) (match_dup 1)))]
+  ""
+  "spu_allocate_stack (operands[0], operands[1]); DONE;")
+
+;; These patterns say how to save and restore the stack pointer.  We need not
+;; save the stack pointer at function or block level since we are careful to
+;; preserve the backchain.  Doing nothing at block level means the stack space
+;; is allocated until the end of the function.  This is currently safe to do
+;; because gcc uses the frame pointer for the whole function, so the worst that
+;; happens is wasted stack space.  That could be bad if a VLA is declared in a
+;; loop, because new space will be allocated every iteration, but users can
+;; work around that case.  Ideally we could detect when we are in a loop and
+;; generate the more complicated code in that case.
+;;
+;; For nonlocal gotos, we must save both the stack pointer and its
+;; backchain and restore both.  Note that in the nonlocal case, the
+;; save area is a memory location.
+
+(define_expand "save_stack_function"
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")]
+  ""
+  "DONE;")
+
+(define_expand "restore_stack_function"
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")]
+  ""
+  "DONE;")
+
+(define_expand "save_stack_block"
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")]
+  ""
+  "DONE; ")
+
+(define_expand "restore_stack_block"
+  [(use (match_operand 0 "spu_reg_operand" ""))
+   (set (match_dup 2) (match_dup 3))
+   (set (match_dup 0) (match_operand 1 "spu_reg_operand" ""))
+   (set (match_dup 3) (match_dup 2))]
+  ""
+  "DONE;")
+
+(define_expand "save_stack_nonlocal"
+  [(match_operand 0 "memory_operand" "")
+   (match_operand 1 "spu_reg_operand" "")]
+  ""
+  "
+  {
+    rtx temp = gen_reg_rtx (Pmode);
+
+    /* Copy the backchain to the first word, sp to the second.  We need to
+       save the back chain because __builtin_apply appears to clobber it. */
+    emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
+    emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
+    emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
+    DONE;
+  }")
+
+(define_expand "restore_stack_nonlocal"
+  [(match_operand 0 "spu_reg_operand" "")
+   (match_operand 1 "memory_operand" "")]
+  ""
+  "
+  {
+    spu_restore_stack_nonlocal(operands[0], operands[1]);
+    DONE;
+  }")
+
+\f
+;; vector patterns
+
+;; Vector initialization
+(define_expand "vec_init<mode>"
+  [(match_operand:V 0 "register_operand" "")
+   (match_operand 1 "" "")]
+  ""
+  {
+    spu_expand_vector_init (operands[0], operands[1]);
+    DONE;
+  })
+
+(define_expand "vec_set<mode>"
+  [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
+   (set (match_dup:TI 3)
+        (unspec:TI [(match_dup:SI 4)
+                   (match_dup:SI 5)
+                   (match_dup:SI 6)] UNSPEC_CPAT))
+   (set (match_operand:V 0 "spu_reg_operand" "")
+       (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
+                  (match_dup:V 0)
+                  (match_dup:TI 3)] UNSPEC_SHUFB))]
+  ""
+  {
+    HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
+    rtx offset = GEN_INT (INTVAL (operands[2]) * size);
+    operands[3] = gen_reg_rtx (TImode);
+    operands[4] = stack_pointer_rtx;
+    operands[5] = offset;
+    operands[6] = GEN_INT (size);
+  })
+
+(define_expand "vec_extract<mode>"
+  [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
+       (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
+                           (parallel [(match_operand 2 "const_int_operand" "i")])))]
+  ""
+  {
+    if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
+      {
+       emit_insn (gen_spu_convert (operands[0], operands[1]));
+       DONE;
+      }
+  })
+
+(define_insn "_vec_extract<mode>"
+  [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
+       (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
+                           (parallel [(match_operand 2 "const_int_operand" "i")])))]
+  ""
+  "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
+  [(set_attr "type" "shuf")])
+
+\f
+;; misc
+
+(define_expand "shufb"
+  [(set (match_operand 0 "spu_reg_operand" "")
+       (unspec [(match_operand 1 "spu_reg_operand" "")
+                (match_operand 2 "spu_reg_operand" "")
+                (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
+  ""
+  {
+    rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
+    PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
+    emit_insn (s);
+    DONE;
+  })
+
+(define_insn "_shufb"
+  [(set (match_operand 0 "spu_reg_operand" "=r")
+       (unspec [(match_operand 1 "spu_reg_operand" "r")
+                (match_operand 2 "spu_reg_operand" "r")
+                (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
+  "operands"
+  "shufb\t%0,%1,%2,%3"
+  [(set_attr "type" "shuf")])
+
+(define_insn "nop"
+  [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
+  ""
+  "nop"
+  [(set_attr "type" "nop")])
+
+(define_insn "nopn"
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
+  ""
+  "nop\t%0"
+  [(set_attr "type" "nop")])
+
+(define_insn "lnop"
+  [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
+  ""
+  "lnop"
+  [(set_attr "type" "lnop")])
+
+(define_insn "iprefetch"
+  [(unspec [(const_int 0)] UNSPEC_IPREFETCH)]
+  ""
+  "hbrp"
+  [(set_attr "type" "iprefetch")])
+
+(define_insn "hbr"
+  [(set (reg:SI 130)
+       (unspec:SI [(match_operand:SI 0 "immediate_operand" "s,s,s")
+                   (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
+   (unspec [(const_int 0)] UNSPEC_HBR)]
+  ""
+  "@
+   hbr\t%0,%1
+   hbrr\t%0,%1
+   hbra\t%0,%1"
+  [(set_attr "type" "hbr")])
+
+(define_insn "sync"
+  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
+   (clobber (mem:BLK (scratch)))]
+  ""
+  "sync"
+  [(set_attr "type" "br")])
+
+(define_insn "syncc"
+  [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
+   (clobber (mem:BLK (scratch)))]
+  ""
+  "syncc"
+  [(set_attr "type" "br")])
+
+(define_insn "dsync"
+  [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
+   (clobber (mem:BLK (scratch)))]
+  ""
+  "dsync"
+  [(set_attr "type" "br")])
+
+\f
+;; convert between any two modes, avoiding any GCC assumptions
+(define_expand "spu_convert"
+  [(set (match_operand 0 "spu_reg_operand" "")
+       (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
+  ""
+  {
+    rtx c = gen__spu_convert (operands[0], operands[1]);
+    PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
+    emit_insn (c);
+    DONE;
+  })
+
+(define_insn "_spu_convert"
+  [(set (match_operand 0 "spu_reg_operand" "=r")
+       (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
+  "operands"
+  ""
+  [(set_attr "type" "convert")
+   (set_attr "length" "0")])
+
+(define_peephole2
+  [(set (match_operand 0 "spu_reg_operand")
+       (unspec [(match_operand 1 "spu_reg_operand")] UNSPEC_CONVERT))]
+  ""
+  [(use (const_int 0))]
+  "")
+
+\f
+;;
+(include "spu-builtins.md")
+
diff --git a/gcc/config/spu/spu.opt b/gcc/config/spu/spu.opt
new file mode 100644 (file)
index 0000000..d234dcd
--- /dev/null
@@ -0,0 +1,50 @@
+; Options for the SPU port of the compiler
+; Copyright (C) 2006 Free Software Foundation, Inc.
+
+; This file is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 2 of the License, or (at your option)
+; any later version.
+
+; This file is distributed in the hope that it will be useful, but WITHOUT
+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this file; see the file COPYING.  If not, write to the Free
+; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+; 02110-1301, USA.
+
+mwarn-reloc
+Target Report Mask(WARN_RELOC)
+Emit warnings when run-time relocations are generated
+
+merror-reloc
+Target Report Mask(ERROR_RELOC)
+Emit errors when run-time relocations are generated
+
+mbranch-cost=
+Target RejectNegative Joined UInteger Var(spu_branch_cost) Init(20)
+Specify cost of branches (Default 20)
+
+msafe-dma
+Target Report RejectNegative Mask(SAFE_DMA)
+Make sure loads and stores are not moved past DMA instructions
+
+munsafe-dma
+Target Report RejectNegative InverseMask(SAFE_DMA)
+volatile must be specified on any memory that is effected by DMA
+
+mbranch-hints
+Target Report Mask(BRANCH_HINTS)
+Generate branch hints for branches
+
+msmall-mem
+Target Report RejectNegative InverseMask(LARGE_MEM)
+Generate code for 18 bit addressing
+
+mlarge-mem
+Target Report RejectNegative Mask(LARGE_MEM)
+Generate code for 32 bit addressing
+
diff --git a/gcc/config/spu/spu_internals.h b/gcc/config/spu/spu_internals.h
new file mode 100644 (file)
index 0000000..752ddb6
--- /dev/null
@@ -0,0 +1,2846 @@
+/* Definitions of Synergistic Processing Unit (SPU). */
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source files 
+   compiled by GCC, this header file does not by itself cause  the resulting 
+   executable to be covered by the GNU General Public License.  This exception 
+   does not however invalidate any other reasons why the executable file might be 
+   covered by the GNU General Public License.  */ 
+
+
+#ifndef  _SPU_INTERNALS_H
+#define _SPU_INTERNALS_H 
+/* For a typical GCC implementation, the vector keyword is defined here
+ * as a macro.  If this macro conflicts with user code the user needs to
+ * undefine it.  An extended GCC implementation may implement this
+ * keyword differently, such that it never conflicts,  and will define
+ * the macro __VECTOR_KEYWORD_SUPPORTED__. */
+#ifndef __VECTOR_KEYWORD_SUPPORTED__
+#define vector __vector
+#endif
+
+
+/*  The spu specific instruction macros, si_*(), correspond 1-1 with
+ *  SPU instructions in the ISA.  The arguments are the same with the
+ *  following exceptions:
+ *   -  any instruction which both reads and writes rt will have an
+ *      extra parameter in the macro.
+ *   -  instructions which append zero to the immediate field assume
+ *      the value given in a macro already has the zeroes appended.
+ *   -  integer/float convert functions expect a value from 0 to 127,
+ *      i.e., the bias is added by the compiler.
+ *
+ *  Parameters named 'imm' accept an integer literal.
+ *  Parameters named 'r[abcdt]' accept a qword argument.
+ *  Parameters named 'scalar' accept a scalar argument.
+ */
+
+#define qword __vector signed char
+
+#define si_lqd(ra,imm)       __builtin_si_lqd(ra,imm)
+#define si_lqx(ra,rb)        __builtin_si_lqx(ra,rb)
+#define si_lqa(imm)          __builtin_si_lqa(imm)
+#define si_lqr(imm)          __builtin_si_lqr(imm)
+#define si_stqd(rt,ra,imm)   __builtin_si_stqd(rt,ra,imm)
+#define si_stqx(rt,ra,rb)    __builtin_si_stqx(rt,ra,rb)
+#define si_stqa(rt,imm)      __builtin_si_stqa(rt,imm)
+#define si_stqr(rt,imm)      __builtin_si_stqr(rt,imm)
+#define si_cbd(ra,imm)       __builtin_si_cbd(ra,imm)
+#define si_cbx(ra,rb)        __builtin_si_cbx(ra,rb)
+#define si_chd(ra,imm)       __builtin_si_chd(ra,imm)
+#define si_chx(ra,rb)        __builtin_si_chx(ra,rb)
+#define si_cwd(ra,imm)       __builtin_si_cwd(ra,imm)
+#define si_cwx(ra,rb)        __builtin_si_cwx(ra,rb)
+#define si_cdd(ra,imm)       __builtin_si_cdd(ra,imm)
+#define si_cdx(ra,rb)        __builtin_si_cdx(ra,rb)
+#define si_ilh(imm)          __builtin_si_ilh(imm)
+#define si_ilhu(imm)         __builtin_si_ilhu(imm)
+#define si_il(imm)           __builtin_si_il(imm)
+#define si_ila(imm)          __builtin_si_ila(imm)
+#define si_iohl(ra,imm)      __builtin_si_iohl(ra,imm)
+#define si_fsmbi(imm)        __builtin_si_fsmbi(imm)
+#define si_ah(ra,rb)         __builtin_si_ah(ra,rb)
+#define si_ahi(ra,imm)       __builtin_si_ahi(ra,imm)
+#define si_a(ra,rb)          __builtin_si_a(ra,rb)
+#define si_ai(ra,imm)        __builtin_si_ai(ra,imm)
+#define si_addx(ra,rb,rt)    __builtin_si_addx(ra,rb,rt)
+#define si_cg(ra,rb)         __builtin_si_cg(ra,rb)
+#define si_cgx(ra,rb,rt)     __builtin_si_cgx(ra,rb,rt)
+#define si_sfh(ra,rb)        __builtin_si_sfh(ra,rb)
+#define si_sfhi(imm,ra)      __builtin_si_sfhi(imm,ra)
+#define si_sf(ra,rb)         __builtin_si_sf(ra,rb)
+#define si_sfi(ra,imm)       __builtin_si_sfi(ra,imm)
+#define si_sfx(ra,rb,rt)     __builtin_si_sfx(ra,rb,rt)
+#define si_bg(ra,rb)         __builtin_si_bg(ra,rb)
+#define si_bgx(ra,rb,rt)     __builtin_si_bgx(ra,rb,rt)
+#define si_mpy(ra,rb)        __builtin_si_mpy(ra,rb)
+#define si_mpyu(ra,rb)       __builtin_si_mpyu(ra,rb)
+#define si_mpyi(ra,imm)      __builtin_si_mpyi(ra,imm)
+#define si_mpyui(ra,imm)     __builtin_si_mpyui(ra,imm)
+#define si_mpya(ra,rb,rc)    __builtin_si_mpya(ra,rb,rc)
+#define si_mpyh(ra,rb)       __builtin_si_mpyh(ra,rb)
+#define si_mpys(ra,rb)       __builtin_si_mpys(ra,rb)
+#define si_mpyhh(ra,rb)      __builtin_si_mpyhh(ra,rb)
+#define si_mpyhhu(ra,rb)     __builtin_si_mpyhhu(ra,rb)
+#define si_mpyhha(ra,rb,rc)  __builtin_si_mpyhha(ra,rb,rc)
+#define si_mpyhhau(ra,rb,rc) __builtin_si_mpyhhau(ra,rb,rc)
+#define si_clz(ra)           __builtin_si_clz(ra)
+#define si_cntb(ra)          __builtin_si_cntb(ra)
+#define si_fsmb(ra)          __builtin_si_fsmb(ra)
+#define si_fsmh(ra)          __builtin_si_fsmh(ra)
+#define si_fsm(ra)           __builtin_si_fsm(ra)
+#define si_gbb(ra)           __builtin_si_gbb(ra)
+#define si_gbh(ra)           __builtin_si_gbh(ra)
+#define si_gb(ra)            __builtin_si_gb(ra)
+#define si_avgb(ra,rb)       __builtin_si_avgb(ra,rb)
+#define si_absdb(ra,rb)      __builtin_si_absdb(ra,rb)
+#define si_sumb(ra,rb)       __builtin_si_sumb(ra,rb)
+#define si_xsbh(ra)          __builtin_si_xsbh(ra)
+#define si_xshw(ra)          __builtin_si_xshw(ra)
+#define si_xswd(ra)          __builtin_si_xswd(ra)
+#define si_and(ra,rb)        __builtin_si_and(ra,rb)
+#define si_andc(ra,rb)       __builtin_si_andc(ra,rb)
+#define si_andbi(ra,imm)     __builtin_si_andbi(ra,imm)
+#define si_andhi(ra,imm)     __builtin_si_andhi(ra,imm)
+#define si_andi(ra,imm)      __builtin_si_andi(ra,imm)
+#define si_or(ra,rb)         __builtin_si_or(ra,rb)
+#define si_orc(ra,rb)        __builtin_si_orc(ra,rb)
+#define si_orbi(ra,imm)      __builtin_si_orbi(ra,imm)
+#define si_orhi(ra,imm)      __builtin_si_orhi(ra,imm)
+#define si_ori(ra,imm)       __builtin_si_ori(ra,imm)
+#define si_orx(ra)           __builtin_si_orx(ra)
+#define si_xor(ra,rb)        __builtin_si_xor(ra,rb)
+#define si_xorbi(ra,imm)     __builtin_si_xorbi(ra,imm)
+#define si_xorhi(ra,imm)     __builtin_si_xorhi(ra,imm)
+#define si_xori(ra,imm)      __builtin_si_xori(ra,imm)
+#define si_nand(ra,rb)       __builtin_si_nand(ra,rb)
+#define si_nor(ra,rb)        __builtin_si_nor(ra,rb)
+#define si_eqv(ra,rb)        __builtin_si_eqv(ra,rb)
+#define si_selb(ra,rb,rc)    __builtin_si_selb(ra,rb,rc)
+#define si_shufb(ra,rb,rc)   __builtin_si_shufb(ra,rb,rc)
+#define si_shlh(ra,rb)       __builtin_si_shlh(ra,rb)
+#define si_shlhi(ra,imm)     __builtin_si_shlhi(ra,imm)
+#define si_shl(ra,rb)        __builtin_si_shl(ra,rb)
+#define si_shli(ra,imm)      __builtin_si_shli(ra,imm)
+#define si_shlqbi(ra,rb)     __builtin_si_shlqbi(ra,rb)
+#define si_shlqbii(ra,imm)   __builtin_si_shlqbii(ra,imm)
+#define si_shlqby(ra,rb)     __builtin_si_shlqby(ra,rb)
+#define si_shlqbyi(ra,imm)   __builtin_si_shlqbyi(ra,imm)
+#define si_shlqbybi(ra,rb)   __builtin_si_shlqbybi(ra,rb)
+#define si_roth(ra,rb)       __builtin_si_roth(ra,rb)
+#define si_rothi(ra,imm)     __builtin_si_rothi(ra,imm)
+#define si_rot(ra,rb)        __builtin_si_rot(ra,rb)
+#define si_roti(ra,imm)      __builtin_si_roti(ra,imm)
+#define si_rotqby(ra,rb)     __builtin_si_rotqby(ra,rb)
+#define si_rotqbyi(ra,imm)   __builtin_si_rotqbyi(ra,imm)
+#define si_rotqbybi(ra,rb)   __builtin_si_rotqbybi(ra,rb)
+#define si_rotqbi(ra,rb)     __builtin_si_rotqbi(ra,rb)
+#define si_rotqbii(ra,imm)   __builtin_si_rotqbii(ra,imm)
+#define si_rothm(ra,rb)      __builtin_si_rothm(ra,rb)
+#define si_rothmi(ra,imm)    __builtin_si_rothmi(ra,imm)
+#define si_rotm(ra,rb)       __builtin_si_rotm(ra,rb)
+#define si_rotmi(ra,imm)     __builtin_si_rotmi(ra,imm)
+#define si_rotqmby(ra,rb)    __builtin_si_rotqmby(ra,rb)
+#define si_rotqmbyi(ra,imm)  __builtin_si_rotqmbyi(ra,imm)
+#define si_rotqmbi(ra,rb)    __builtin_si_rotqmbi(ra,rb)
+#define si_rotqmbii(ra,imm)  __builtin_si_rotqmbii(ra,imm)
+#define si_rotqmbybi(ra,rb)  __builtin_si_rotqmbybi(ra,rb)
+#define si_rotmah(ra,rb)     __builtin_si_rotmah(ra,rb)
+#define si_rotmahi(ra,imm)   __builtin_si_rotmahi(ra,imm)
+#define si_rotma(ra,rb)      __builtin_si_rotma(ra,rb)
+#define si_rotmai(ra,imm)    __builtin_si_rotmai(ra,imm)
+#define si_heq(ra,rb)        __builtin_si_heq(ra,rb)
+#define si_heqi(ra,imm)      __builtin_si_heqi(ra,imm)
+#define si_hgt(ra,rb)        __builtin_si_hgt(ra,rb)
+#define si_hgti(ra,imm)      __builtin_si_hgti(ra,imm)
+#define si_hlgt(ra,rb)       __builtin_si_hlgt(ra,rb)
+#define si_hlgti(ra,imm)     __builtin_si_hlgti(ra,imm)
+#define si_ceqb(ra,rb)       __builtin_si_ceqb(ra,rb)
+#define si_ceqbi(ra,imm)     __builtin_si_ceqbi(ra,imm)
+#define si_ceqh(ra,rb)       __builtin_si_ceqh(ra,rb)
+#define si_ceqhi(ra,imm)     __builtin_si_ceqhi(ra,imm)
+#define si_ceq(ra,rb)        __builtin_si_ceq(ra,rb)
+#define si_ceqi(ra,imm)      __builtin_si_ceqi(ra,imm)
+#define si_cgtb(ra,rb)       __builtin_si_cgtb(ra,rb)
+#define si_cgtbi(ra,imm)     __builtin_si_cgtbi(ra,imm)
+#define si_cgth(ra,rb)       __builtin_si_cgth(ra,rb)
+#define si_cgthi(ra,imm)     __builtin_si_cgthi(ra,imm)
+#define si_cgt(ra,rb)        __builtin_si_cgt(ra,rb)
+#define si_cgti(ra,imm)      __builtin_si_cgti(ra,imm)
+#define si_clgtb(ra,rb)      __builtin_si_clgtb(ra,rb)
+#define si_clgtbi(ra,imm)    __builtin_si_clgtbi(ra,imm)
+#define si_clgth(ra,rb)      __builtin_si_clgth(ra,rb)
+#define si_clgthi(ra,imm)    __builtin_si_clgthi(ra,imm)
+#define si_clgt(ra,rb)       __builtin_si_clgt(ra,rb)
+#define si_clgti(ra,imm)     __builtin_si_clgti(ra,imm)
+#define si_fa(ra,rb)         __builtin_si_fa(ra,rb)
+#define si_dfa(ra,rb)        __builtin_si_dfa(ra,rb)
+#define si_fs(ra,rb)         __builtin_si_fs(ra,rb)
+#define si_dfs(ra,rb)        __builtin_si_dfs(ra,rb)
+#define si_fm(ra,rb)         __builtin_si_fm(ra,rb)
+#define si_dfm(ra,rb)        __builtin_si_dfm(ra,rb)
+#define si_fma(ra,rb,rc)     __builtin_si_fma(ra,rb,rc)
+#define si_dfma(ra,rb,rc)    __builtin_si_dfma(ra,rb,rc)
+#define si_dfnma(ra,rb,rc)   __builtin_si_dfnma(ra,rb,rc)
+#define si_fnms(ra,rb,rc)    __builtin_si_fnms(ra,rb,rc)
+#define si_dfnms(ra,rb,rc)   __builtin_si_dfnms(ra,rb,rc)
+#define si_fms(ra,rb,rc)     __builtin_si_fms(ra,rb,rc)
+#define si_dfms(ra,rb,rc)    __builtin_si_dfms(ra,rb,rc)
+#define si_frest(ra)         __builtin_si_frest(ra)
+#define si_frsqest(ra)       __builtin_si_frsqest(ra)
+#define si_fi(ra,rb)         __builtin_si_fi(ra,rb)
+#define si_csflt(ra,imm)     __builtin_si_csflt(ra,imm)
+#define si_cflts(ra,imm)     __builtin_si_cflts(ra,imm)
+#define si_cuflt(ra,imm)     __builtin_si_cuflt(ra,imm)
+#define si_cfltu(ra,imm)     __builtin_si_cfltu(ra,imm)
+#define si_frds(ra)          __builtin_si_frds(ra)
+#define si_fesd(ra)          __builtin_si_fesd(ra)
+#define si_fceq(ra,rb)       __builtin_si_fceq(ra,rb)
+#define si_fcmeq(ra,rb)      __builtin_si_fcmeq(ra,rb)
+#define si_fcgt(ra,rb)       __builtin_si_fcgt(ra,rb)
+#define si_fcmgt(ra,rb)      __builtin_si_fcmgt(ra,rb)
+#define si_stop(imm)         __builtin_si_stop(imm)
+#define si_stopd(ra,rb,rc)   __builtin_si_stopd(ra,rb,rc)
+#define si_lnop()            __builtin_si_lnop()
+#define si_nop()             __builtin_si_nop()
+#define si_sync()            __builtin_si_sync()
+#define si_syncc()           __builtin_si_syncc()
+#define si_dsync()           __builtin_si_dsync()
+#define si_mfspr(imm)        __builtin_si_mfspr(imm)
+#define si_mtspr(imm,ra)     __builtin_si_mtspr(imm,ra)
+#define si_fscrrd()          __builtin_si_fscrrd()
+#define si_fscrwr(ra)        __builtin_si_fscrwr(ra)
+#define si_rdch(imm)         __builtin_si_rdch(imm)
+#define si_rchcnt(imm)       __builtin_si_rchcnt(imm)
+#define si_wrch(imm,ra)      __builtin_si_wrch(imm,ra)
+
+#define si_from_char(scalar)    __builtin_si_from_char(scalar)
+#define si_from_uchar(scalar)   __builtin_si_from_uchar(scalar)
+#define si_from_short(scalar)   __builtin_si_from_short(scalar)
+#define si_from_ushort(scalar)  __builtin_si_from_ushort(scalar)
+#define si_from_int(scalar)     __builtin_si_from_int(scalar)
+#define si_from_uint(scalar)    __builtin_si_from_uint(scalar)
+#define si_from_llong(scalar)   __builtin_si_from_long(scalar)
+#define si_from_ullong(scalar)  __builtin_si_from_ulong(scalar)
+#define si_from_float(scalar)   __builtin_si_from_float(scalar)
+#define si_from_double(scalar)  __builtin_si_from_double(scalar)
+#define si_from_ptr(scalar)     __builtin_si_from_ptr(scalar)
+
+#define si_to_char(ra)      __builtin_si_to_char(ra)
+#define si_to_uchar(ra)     __builtin_si_to_uchar(ra)
+#define si_to_short(ra)     __builtin_si_to_short(ra)
+#define si_to_ushort(ra)    __builtin_si_to_ushort(ra)
+#define si_to_int(ra)       __builtin_si_to_int(ra)
+#define si_to_uint(ra)      __builtin_si_to_uint(ra)
+#define si_to_llong(ra)     __builtin_si_to_long(ra)
+#define si_to_ullong(ra)    __builtin_si_to_ulong(ra)
+#define si_to_float(ra)     __builtin_si_to_float(ra)
+#define si_to_double(ra)    __builtin_si_to_double(ra)
+#define si_to_ptr(ra)       __builtin_si_to_ptr(ra)
+
+#define __align_hint(ptr,base,offset) __builtin_spu_align_hint(ptr,base,offset)
+
+#ifndef __cplusplus
+
+/* generic spu_* intrinisics */ 
+
+#define spu_splats(scalar)        __builtin_spu_splats(scalar) 
+#define spu_convtf(ra,imm)        __builtin_spu_convtf(ra,imm)
+#define spu_convts(ra,imm)        __builtin_spu_convts(ra,imm)
+#define spu_convtu(ra,imm)        __builtin_spu_convtu(ra,imm) 
+#define spu_extend(ra)            __builtin_spu_extend(ra) 
+#define spu_roundtf(ra)           __builtin_spu_roundtf(ra) 
+#define spu_add(ra,rb)            __builtin_spu_add(ra,rb) 
+#define spu_addx(ra,rb,rt)        __builtin_spu_addx(ra,rb,rt) 
+#define spu_genc(ra,rb)           __builtin_spu_genc(ra,rb) 
+#define spu_gencx(ra,rb,rt)       __builtin_spu_gencx(ra,rb,rt) 
+#define spu_madd(ra,rb,rc)        __builtin_spu_madd(ra,rb,rc)
+#define spu_nmadd(ra,rb,rc)       __builtin_spu_nmadd(ra,rb,rc)
+#define spu_mhhadd(ra,rb,rc)      __builtin_spu_mhhadd(ra,rb,rc)
+#define spu_msub(ra,rb,rc)        __builtin_spu_msub(ra,rb,rc) 
+#define spu_mul(ra,rb)            __builtin_spu_mul(ra,rb) 
+#define spu_mulh(ra,rb)           __builtin_spu_mulh(ra,rb) 
+#define spu_mule(ra,rb)           __builtin_spu_mule(ra,rb) 
+#define spu_mulo(ra,rb)           __builtin_spu_mulo(ra,rb) 
+#define spu_mulsr(ra,rb)          __builtin_spu_mulsr(ra,rb) 
+#define spu_nmsub(ra,rb,rc)       __builtin_spu_nmsub(ra,rb,rc) 
+#define spu_sub(ra,rb)            __builtin_spu_sub(ra,rb)
+#define spu_subx(ra,rb,rt)        __builtin_spu_subx(ra,rb,rt) 
+#define spu_genb(ra,rb)           __builtin_spu_genb(ra,rb) 
+#define spu_genbx(ra,rb,rt)       __builtin_spu_genbx(ra,rb,rt) 
+#define spu_absd(ra,rb)           __builtin_spu_absd(ra,rb) 
+#define spu_avg(ra,rb)            __builtin_spu_avg(ra,rb) 
+#define spu_sumb(ra,rb)           __builtin_spu_sumb(ra,rb) 
+#define spu_bisled(ra)            __builtin_spu_bisled(ra, 0)
+#define spu_bisled_d(ra)          __builtin_spu_bisled_d(ra, 0)
+#define spu_bisled_e(ra)          __builtin_spu_bisled_e(ra, 0)
+#define spu_cmpabseq(ra,rb)       __builtin_spu_cmpabseq(ra,rb) 
+#define spu_cmpabsgt(ra,rb)       __builtin_spu_cmpabsgt(ra,rb) 
+#define spu_cmpeq(ra,rb)          __builtin_spu_cmpeq(ra,rb) 
+#define spu_cmpgt(ra,rb)          __builtin_spu_cmpgt(ra,rb) 
+#define spu_hcmpeq(ra,rb)         __builtin_spu_hcmpeq(ra,rb) 
+#define spu_hcmpgt(ra,rb)         __builtin_spu_hcmpgt(ra,rb) 
+#define spu_cntb(ra)              __builtin_spu_cntb(ra) 
+#define spu_cntlz(ra)             __builtin_spu_cntlz(ra) 
+#define spu_gather(ra)            __builtin_spu_gather(ra) 
+#define spu_maskb(ra)             __builtin_spu_maskb(ra) 
+#define spu_maskh(ra)             __builtin_spu_maskh(ra) 
+#define spu_maskw(ra)             __builtin_spu_maskw(ra) 
+#define spu_sel(ra,rb,rc)         __builtin_spu_sel(ra,rb,rc) 
+#define spu_shuffle(ra,rb,rc)     __builtin_spu_shuffle(ra,rb,rc) 
+#define spu_and(ra,rb)            __builtin_spu_and(ra,rb) 
+#define spu_andc(ra,rb)           __builtin_spu_andc(ra,rb) 
+#define spu_eqv(ra,rb)            __builtin_spu_eqv(ra,rb) 
+#define spu_nand(ra,rb)           __builtin_spu_nand(ra,rb)
+#define spu_nor(ra,rb)            __builtin_spu_nor(ra,rb) 
+#define spu_or(ra,rb)             __builtin_spu_or(ra,rb) 
+#define spu_orc(ra,rb)            __builtin_spu_orc(ra,rb) 
+#define spu_orx(ra)               __builtin_spu_orx(ra)
+#define spu_xor(ra,rb)            __builtin_spu_xor(ra,rb) 
+#define spu_rl(ra,rb)             __builtin_spu_rl(ra,rb) 
+#define spu_rlqw(ra,count)        __builtin_spu_rlqw(ra,count) 
+#define spu_rlqwbyte(ra,count)    __builtin_spu_rlqwbyte(ra,count) 
+#define spu_rlqwbytebc(ra,count)  __builtin_spu_rlqwbytebc(ra,count) 
+#define spu_rlmask(ra,rb)         __builtin_spu_rlmask(ra,rb) 
+#define spu_rlmaska(ra,rb)        __builtin_spu_rlmaska(ra,rb) 
+#define spu_rlmaskqw(ra,rb)       __builtin_spu_rlmaskqw(ra,rb) 
+#define spu_rlmaskqwbyte(ra,rb)   __builtin_spu_rlmaskqwbyte(ra,rb) 
+#define spu_rlmaskqwbytebc(ra,rb) __builtin_spu_rlmaskqwbytebc(ra,rb) 
+#define spu_sl(ra,rb)             __builtin_spu_sl(ra,rb) 
+#define spu_slqw(ra,rb)           __builtin_spu_slqw(ra,rb) 
+#define spu_slqwbyte(ra,rb)       __builtin_spu_slqwbyte(ra,rb) 
+#define spu_slqwbytebc(ra,rb)     __builtin_spu_slqwbytebc(ra,rb) 
+#define spu_extract(ra,pos)       __builtin_spu_extract(ra,pos) 
+#define spu_insert(scalar,ra,pos) __builtin_spu_insert(scalar,ra,pos) 
+#define spu_promote(scalar,pos)   __builtin_spu_promote(scalar,pos) 
+
+#else /* __cplusplus */
+
+/* A bit of a hack...  Float conversion needs an immediate operand.
+ * always_inline doesn't help because the compiler generates an error
+ * before inlining happens. */
+static inline vec_float4 __hack_spu_convtf (vec_int4, vec_float4, vec_float4) __attribute__((__always_inline__));
+static inline vec_float4 __hack_spu_convtf (vec_uint4, vec_float4, vec_float4) __attribute__((__always_inline__));
+static inline vec_float4
+__hack_spu_convtf (vec_int4 ra, vec_float4 from_signed, vec_float4 from_unsigned)
+{
+  (void)ra;
+  (void)from_unsigned;
+  return from_signed;
+}
+static inline vec_float4
+__hack_spu_convtf (vec_uint4 ra, vec_float4 from_signed, vec_float4 from_unsigned)
+{
+  (void)ra;
+  (void)from_signed;
+  return from_unsigned;
+}
+#define spu_convtf(ra,imm) \
+  __hack_spu_convtf((ra), \
+                   __builtin_spu_convtf_1((vec_int4)(ra), (imm)), \
+                   __builtin_spu_convtf_0((vec_uint4)(ra), (imm)))
+
+/* The following defines and functions were created automatically from
+ * spu_builtins.def. */
+#define spu_convts(a, b)       __builtin_spu_convts (a, b)
+#define spu_convtu(a, b)       __builtin_spu_convtu (a, b)
+#define spu_roundtf(a)         __builtin_spu_roundtf (a)
+#define spu_mulh(a, b)         __builtin_spu_mulh (a, b)
+#define spu_mulsr(a, b)                __builtin_spu_mulsr (a, b)
+#define spu_frest(a)           __builtin_spu_frest (a)
+#define spu_frsqest(a)         __builtin_spu_frsqest (a)
+#define spu_nmadd(a, b, c)     __builtin_spu_nmadd (a, b, c)
+#define spu_absd(a, b)         __builtin_spu_absd (a, b)
+#define spu_avg(a, b)          __builtin_spu_avg (a, b)
+#define spu_sumb(a, b)         __builtin_spu_sumb (a, b)
+#define spu_bisled(a)          __builtin_spu_bisled (a, 0)
+#define spu_bisled_d(a)                __builtin_spu_bisled_d (a, 0)
+#define spu_bisled_e(a)                __builtin_spu_bisled_e (a, 0)
+#define spu_cmpabseq(a, b)     __builtin_spu_cmpabseq (a, b)
+#define spu_cmpabsgt(a, b)     __builtin_spu_cmpabsgt (a, b)
+
+static inline vec_short8 spu_extend (vec_char16 a) __attribute__((__always_inline__));
+static inline vec_int4 spu_extend (vec_short8 a) __attribute__((__always_inline__));
+static inline vec_llong2 spu_extend (vec_int4 a) __attribute__((__always_inline__));
+static inline vec_double2 spu_extend (vec_float4 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_add (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_add (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_add (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_add (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_add (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_add (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_add (vec_ushort8 a, unsigned short b) __attribute__((__always_inline__));
+static inline vec_short8 spu_add (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_add (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_add (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_addx (vec_int4 a, vec_int4 b, vec_int4 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_addx (vec_uint4 a, vec_uint4 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_genc (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_genc (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_gencx (vec_int4 a, vec_int4 b, vec_int4 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gencx (vec_uint4 a, vec_uint4 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_madd (vec_short8 a, vec_short8 b, vec_int4 c) __attribute__((__always_inline__));
+static inline vec_float4 spu_madd (vec_float4 a, vec_float4 b, vec_float4 c) __attribute__((__always_inline__));
+static inline vec_double2 spu_madd (vec_double2 a, vec_double2 b, vec_double2 c) __attribute__((__always_inline__));
+static inline vec_float4 spu_msub (vec_float4 a, vec_float4 b, vec_float4 c) __attribute__((__always_inline__));
+static inline vec_double2 spu_msub (vec_double2 a, vec_double2 b, vec_double2 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_mhhadd (vec_ushort8 a, vec_ushort8 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_mhhadd (vec_short8 a, vec_short8 b, vec_int4 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_mule (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_mule (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_mul (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_mul (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_mulo (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_mulo (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_mulo (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_mulo (vec_ushort8 a, unsigned short b) __attribute__((__always_inline__));
+static inline vec_float4 spu_nmsub (vec_float4 a, vec_float4 b, vec_float4 c) __attribute__((__always_inline__));
+static inline vec_double2 spu_nmsub (vec_double2 a, vec_double2 b, vec_double2 c) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_sub (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_sub (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_sub (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_sub (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_sub (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_sub (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_sub (unsigned short a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_sub (short a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_sub (unsigned int a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_sub (int a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_subx (vec_uint4 a, vec_uint4 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_subx (vec_int4 a, vec_int4 b, vec_int4 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_genb (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_genb (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_genbx (vec_uint4 a, vec_uint4 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_genbx (vec_int4 a, vec_int4 b, vec_int4 c) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpeq (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpeq (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpeq (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpeq (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpeq (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpeq (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpeq (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpeq (vec_uchar16 a, unsigned char b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpeq (vec_char16 a, signed char b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpeq (vec_ushort8 a, unsigned short b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpeq (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpeq (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpeq (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpgt (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpgt (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpgt (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpgt (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpgt (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpgt (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpgt (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpgt (vec_uchar16 a, unsigned char b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cmpgt (vec_char16 a, signed char b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpgt (vec_ushort8 a, unsigned short b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_cmpgt (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpgt (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cmpgt (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline void spu_hcmpeq (int a, int b) __attribute__((__always_inline__));
+static inline void spu_hcmpeq (unsigned int a, unsigned int b) __attribute__((__always_inline__));
+static inline void spu_hcmpgt (int a, int b) __attribute__((__always_inline__));
+static inline void spu_hcmpgt (unsigned int a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cntb (vec_char16 a) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_cntb (vec_uchar16 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cntlz (vec_int4 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cntlz (vec_uint4 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_cntlz (vec_float4 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gather (vec_int4 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gather (vec_uint4 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gather (vec_short8 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gather (vec_ushort8 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gather (vec_char16 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gather (vec_uchar16 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_gather (vec_float4 a) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_maskb (unsigned short a) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_maskb (short a) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_maskb (unsigned int a) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_maskb (int a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_maskh (unsigned char a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_maskh (signed char a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_maskh (char a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_maskh (unsigned short a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_maskh (short a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_maskh (unsigned int a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_maskh (int a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_maskw (unsigned char a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_maskw (signed char a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_maskw (char a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_maskw (unsigned short a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_maskw (short a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_maskw (unsigned int a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_maskw (int a) __attribute__((__always_inline__));
+static inline vec_llong2 spu_sel (vec_llong2 a, vec_llong2 b, vec_ullong2 c) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_sel (vec_ullong2 a, vec_ullong2 b, vec_ullong2 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_sel (vec_int4 a, vec_int4 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_sel (vec_uint4 a, vec_uint4 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_short8 spu_sel (vec_short8 a, vec_short8 b, vec_ushort8 c) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_sel (vec_ushort8 a, vec_ushort8 b, vec_ushort8 c) __attribute__((__always_inline__));
+static inline vec_char16 spu_sel (vec_char16 a, vec_char16 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_sel (vec_uchar16 a, vec_uchar16 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_float4 spu_sel (vec_float4 a, vec_float4 b, vec_uint4 c) __attribute__((__always_inline__));
+static inline vec_double2 spu_sel (vec_double2 a, vec_double2 b, vec_ullong2 c) __attribute__((__always_inline__));
+static inline vec_llong2 spu_sel (vec_llong2 a, vec_llong2 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_sel (vec_ullong2 a, vec_ullong2 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_sel (vec_int4 a, vec_int4 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_sel (vec_uint4 a, vec_uint4 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_short8 spu_sel (vec_short8 a, vec_short8 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_sel (vec_ushort8 a, vec_ushort8 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_float4 spu_sel (vec_float4 a, vec_float4 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_double2 spu_sel (vec_double2 a, vec_double2 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_shuffle (vec_uchar16 a, vec_uchar16 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_char16 spu_shuffle (vec_char16 a, vec_char16 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_shuffle (vec_ushort8 a, vec_ushort8 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_short8 spu_shuffle (vec_short8 a, vec_short8 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_shuffle (vec_uint4 a, vec_uint4 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_int4 spu_shuffle (vec_int4 a, vec_int4 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_shuffle (vec_ullong2 a, vec_ullong2 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_llong2 spu_shuffle (vec_llong2 a, vec_llong2 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_float4 spu_shuffle (vec_float4 a, vec_float4 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_double2 spu_shuffle (vec_double2 a, vec_double2 b, vec_uchar16 c) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_and (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_and (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_and (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_and (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_and (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_and (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_and (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_and (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_and (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_and (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_and (vec_uchar16 a, unsigned char b) __attribute__((__always_inline__));
+static inline vec_char16 spu_and (vec_char16 a, signed char b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_and (vec_ushort8 a, unsigned short b) __attribute__((__always_inline__));
+static inline vec_short8 spu_and (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_and (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_and (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_andc (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_andc (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_andc (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_andc (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_andc (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_andc (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_andc (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_andc (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_andc (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_andc (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_eqv (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_eqv (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_eqv (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_eqv (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_eqv (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_eqv (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_eqv (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_eqv (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_eqv (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_eqv (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_nand (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_nand (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_nand (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_nand (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_nand (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_nand (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_nand (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_nand (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_nand (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_nand (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_nor (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_nor (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_nor (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_nor (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_nor (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_nor (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_nor (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_nor (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_nor (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_nor (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_or (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_or (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_or (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_or (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_or (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_or (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_or (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_or (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_or (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_or (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_or (vec_uchar16 a, unsigned char b) __attribute__((__always_inline__));
+static inline vec_char16 spu_or (vec_char16 a, signed char b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_or (vec_ushort8 a, unsigned short b) __attribute__((__always_inline__));
+static inline vec_short8 spu_or (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_or (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_or (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_orc (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_orc (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_orc (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_orc (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_orc (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_orc (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_orc (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_orc (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_orc (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_orc (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_orx (vec_int4 a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_orx (vec_uint4 a) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_xor (vec_uchar16 a, vec_uchar16 b) __attribute__((__always_inline__));
+static inline vec_char16 spu_xor (vec_char16 a, vec_char16 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_xor (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_xor (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_xor (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_xor (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_xor (vec_ullong2 a, vec_ullong2 b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_xor (vec_llong2 a, vec_llong2 b) __attribute__((__always_inline__));
+static inline vec_float4 spu_xor (vec_float4 a, vec_float4 b) __attribute__((__always_inline__));
+static inline vec_double2 spu_xor (vec_double2 a, vec_double2 b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_xor (vec_uchar16 a, unsigned char b) __attribute__((__always_inline__));
+static inline vec_char16 spu_xor (vec_char16 a, signed char b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_xor (vec_ushort8 a, unsigned short b) __attribute__((__always_inline__));
+static inline vec_short8 spu_xor (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_xor (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_xor (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rl (vec_ushort8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rl (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rl (vec_uint4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rl (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rl (vec_ushort8 a, short b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rl (vec_short8 a, short b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rl (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rl (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_rlqw (vec_uchar16 a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_rlqw (vec_char16 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlqw (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlqw (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlqw (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlqw (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_rlqw (vec_ullong2 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_rlqw (vec_llong2 a, int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_rlqw (vec_float4 a, int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_rlqw (vec_double2 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_rlqwbyte (vec_uchar16 a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_rlqwbyte (vec_char16 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlqwbyte (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlqwbyte (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlqwbyte (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlqwbyte (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_rlqwbyte (vec_ullong2 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_rlqwbyte (vec_llong2 a, int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_rlqwbyte (vec_float4 a, int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_rlqwbyte (vec_double2 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_rlqwbytebc (vec_uchar16 a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_rlqwbytebc (vec_char16 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlqwbytebc (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlqwbytebc (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlqwbytebc (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlqwbytebc (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_rlqwbytebc (vec_ullong2 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_rlqwbytebc (vec_llong2 a, int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_rlqwbytebc (vec_float4 a, int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_rlqwbytebc (vec_double2 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlmask (vec_ushort8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlmask (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlmask (vec_uint4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlmask (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlmask (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlmask (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlmask (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlmask (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlmaska (vec_ushort8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlmaska (vec_short8 a, vec_short8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlmaska (vec_uint4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlmaska (vec_int4 a, vec_int4 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlmaska (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlmaska (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlmaska (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlmaska (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_rlmaskqw (vec_uchar16 a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_rlmaskqw (vec_char16 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlmaskqw (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlmaskqw (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlmaskqw (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlmaskqw (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_rlmaskqw (vec_ullong2 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_rlmaskqw (vec_llong2 a, int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_rlmaskqw (vec_float4 a, int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_rlmaskqw (vec_double2 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_rlmaskqwbyte (vec_uchar16 a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_rlmaskqwbyte (vec_char16 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlmaskqwbyte (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlmaskqwbyte (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlmaskqwbyte (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlmaskqwbyte (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_rlmaskqwbyte (vec_ullong2 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_rlmaskqwbyte (vec_llong2 a, int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_rlmaskqwbyte (vec_float4 a, int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_rlmaskqwbyte (vec_double2 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_rlmaskqwbytebc (vec_uchar16 a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_rlmaskqwbytebc (vec_char16 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_rlmaskqwbytebc (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_rlmaskqwbytebc (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_rlmaskqwbytebc (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_rlmaskqwbytebc (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_rlmaskqwbytebc (vec_ullong2 a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_rlmaskqwbytebc (vec_llong2 a, int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_rlmaskqwbytebc (vec_float4 a, int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_rlmaskqwbytebc (vec_double2 a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_sl (vec_ushort8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_short8 spu_sl (vec_short8 a, vec_ushort8 b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_sl (vec_uint4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_int4 spu_sl (vec_int4 a, vec_uint4 b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_sl (vec_ushort8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_sl (vec_short8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_sl (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_sl (vec_int4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_slqw (vec_llong2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_slqw (vec_ullong2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_slqw (vec_int4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_slqw (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_slqw (vec_short8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_slqw (vec_ushort8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_slqw (vec_char16 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_slqw (vec_uchar16 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_slqw (vec_float4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_slqw (vec_double2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_slqwbyte (vec_llong2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_slqwbyte (vec_ullong2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_slqwbyte (vec_int4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_slqwbyte (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_slqwbyte (vec_short8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_slqwbyte (vec_ushort8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_slqwbyte (vec_char16 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_slqwbyte (vec_uchar16 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_slqwbyte (vec_float4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_slqwbyte (vec_double2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_slqwbytebc (vec_llong2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_slqwbytebc (vec_ullong2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_slqwbytebc (vec_int4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_slqwbytebc (vec_uint4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_slqwbytebc (vec_short8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_slqwbytebc (vec_ushort8 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_slqwbytebc (vec_char16 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_slqwbytebc (vec_uchar16 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_slqwbytebc (vec_float4 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_slqwbytebc (vec_double2 a, unsigned int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_splats (unsigned char a) __attribute__((__always_inline__));
+static inline vec_char16 spu_splats (signed char a) __attribute__((__always_inline__));
+static inline vec_char16 spu_splats (char a) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_splats (unsigned short a) __attribute__((__always_inline__));
+static inline vec_short8 spu_splats (short a) __attribute__((__always_inline__));
+static inline vec_uint4 spu_splats (unsigned int a) __attribute__((__always_inline__));
+static inline vec_int4 spu_splats (int a) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_splats (unsigned long long a) __attribute__((__always_inline__));
+static inline vec_llong2 spu_splats (long long a) __attribute__((__always_inline__));
+static inline vec_float4 spu_splats (float a) __attribute__((__always_inline__));
+static inline vec_double2 spu_splats (double a) __attribute__((__always_inline__));
+static inline unsigned char spu_extract (vec_uchar16 a, int b) __attribute__((__always_inline__));
+static inline signed char spu_extract (vec_char16 a, int b) __attribute__((__always_inline__));
+static inline unsigned short spu_extract (vec_ushort8 a, int b) __attribute__((__always_inline__));
+static inline short spu_extract (vec_short8 a, int b) __attribute__((__always_inline__));
+static inline unsigned int spu_extract (vec_uint4 a, int b) __attribute__((__always_inline__));
+static inline int spu_extract (vec_int4 a, int b) __attribute__((__always_inline__));
+static inline unsigned long long spu_extract (vec_ullong2 a, int b) __attribute__((__always_inline__));
+static inline long long spu_extract (vec_llong2 a, int b) __attribute__((__always_inline__));
+static inline float spu_extract (vec_float4 a, int b) __attribute__((__always_inline__));
+static inline double spu_extract (vec_double2 a, int b) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_insert (unsigned char a, vec_uchar16 b, int c) __attribute__((__always_inline__));
+static inline vec_char16 spu_insert (signed char a, vec_char16 b, int c) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_insert (unsigned short a, vec_ushort8 b, int c) __attribute__((__always_inline__));
+static inline vec_short8 spu_insert (short a, vec_short8 b, int c) __attribute__((__always_inline__));
+static inline vec_uint4 spu_insert (unsigned int a, vec_uint4 b, int c) __attribute__((__always_inline__));
+static inline vec_int4 spu_insert (int a, vec_int4 b, int c) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_insert (unsigned long long a, vec_ullong2 b, int c) __attribute__((__always_inline__));
+static inline vec_llong2 spu_insert (long long a, vec_llong2 b, int c) __attribute__((__always_inline__));
+static inline vec_float4 spu_insert (float a, vec_float4 b, int c) __attribute__((__always_inline__));
+static inline vec_double2 spu_insert (double a, vec_double2 b, int c) __attribute__((__always_inline__));
+static inline vec_uchar16 spu_promote (unsigned char a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_promote (signed char a, int b) __attribute__((__always_inline__));
+static inline vec_char16 spu_promote (char a, int b) __attribute__((__always_inline__));
+static inline vec_ushort8 spu_promote (unsigned short a, int b) __attribute__((__always_inline__));
+static inline vec_short8 spu_promote (short a, int b) __attribute__((__always_inline__));
+static inline vec_uint4 spu_promote (unsigned int a, int b) __attribute__((__always_inline__));
+static inline vec_int4 spu_promote (int a, int b) __attribute__((__always_inline__));
+static inline vec_ullong2 spu_promote (unsigned long long a, int b) __attribute__((__always_inline__));
+static inline vec_llong2 spu_promote (long long a, int b) __attribute__((__always_inline__));
+static inline vec_float4 spu_promote (float a, int b) __attribute__((__always_inline__));
+static inline vec_double2 spu_promote (double a, int b) __attribute__((__always_inline__));
+
+static inline vec_short8
+spu_extend (vec_char16 a)
+{
+  return __builtin_spu_extend_0 (a);
+}
+static inline vec_int4
+spu_extend (vec_short8 a)
+{
+  return __builtin_spu_extend_1 (a);
+}
+static inline vec_llong2
+spu_extend (vec_int4 a)
+{
+  return __builtin_spu_extend_2 (a);
+}
+static inline vec_double2
+spu_extend (vec_float4 a)
+{
+  return __builtin_spu_extend_3 (a);
+}
+static inline vec_uint4
+spu_add (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_add_0 (a, b);
+}
+static inline vec_int4
+spu_add (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_add_1 (a, b);
+}
+static inline vec_ushort8
+spu_add (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_add_2 (a, b);
+}
+static inline vec_short8
+spu_add (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_add_3 (a, b);
+}
+static inline vec_float4
+spu_add (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_add_4 (a, b);
+}
+static inline vec_double2
+spu_add (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_add_5 (a, b);
+}
+static inline vec_ushort8
+spu_add (vec_ushort8 a, unsigned short b)
+{
+  return __builtin_spu_add_6 (a, b);
+}
+static inline vec_short8
+spu_add (vec_short8 a, short b)
+{
+  return __builtin_spu_add_7 (a, b);
+}
+static inline vec_uint4
+spu_add (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_add_8 (a, b);
+}
+static inline vec_int4
+spu_add (vec_int4 a, int b)
+{
+  return __builtin_spu_add_9 (a, b);
+}
+static inline vec_int4
+spu_addx (vec_int4 a, vec_int4 b, vec_int4 c)
+{
+  return __builtin_spu_addx_0 (a, b, c);
+}
+static inline vec_uint4
+spu_addx (vec_uint4 a, vec_uint4 b, vec_uint4 c)
+{
+  return __builtin_spu_addx_1 (a, b, c);
+}
+static inline vec_int4
+spu_genc (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_genc_0 (a, b);
+}
+static inline vec_uint4
+spu_genc (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_genc_1 (a, b);
+}
+static inline vec_int4
+spu_gencx (vec_int4 a, vec_int4 b, vec_int4 c)
+{
+  return __builtin_spu_gencx_0 (a, b, c);
+}
+static inline vec_uint4
+spu_gencx (vec_uint4 a, vec_uint4 b, vec_uint4 c)
+{
+  return __builtin_spu_gencx_1 (a, b, c);
+}
+static inline vec_int4
+spu_madd (vec_short8 a, vec_short8 b, vec_int4 c)
+{
+  return __builtin_spu_madd_0 (a, b, c);
+}
+static inline vec_float4
+spu_madd (vec_float4 a, vec_float4 b, vec_float4 c)
+{
+  return __builtin_spu_madd_1 (a, b, c);
+}
+static inline vec_double2
+spu_madd (vec_double2 a, vec_double2 b, vec_double2 c)
+{
+  return __builtin_spu_madd_2 (a, b, c);
+}
+static inline vec_float4
+spu_msub (vec_float4 a, vec_float4 b, vec_float4 c)
+{
+  return __builtin_spu_msub_0 (a, b, c);
+}
+static inline vec_double2
+spu_msub (vec_double2 a, vec_double2 b, vec_double2 c)
+{
+  return __builtin_spu_msub_1 (a, b, c);
+}
+static inline vec_uint4
+spu_mhhadd (vec_ushort8 a, vec_ushort8 b, vec_uint4 c)
+{
+  return __builtin_spu_mhhadd_0 (a, b, c);
+}
+static inline vec_int4
+spu_mhhadd (vec_short8 a, vec_short8 b, vec_int4 c)
+{
+  return __builtin_spu_mhhadd_1 (a, b, c);
+}
+static inline vec_uint4
+spu_mule (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_mule_0 (a, b);
+}
+static inline vec_int4
+spu_mule (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_mule_1 (a, b);
+}
+static inline vec_float4
+spu_mul (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_mul_0 (a, b);
+}
+static inline vec_double2
+spu_mul (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_mul_1 (a, b);
+}
+static inline vec_int4
+spu_mulo (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_mulo_0 (a, b);
+}
+static inline vec_uint4
+spu_mulo (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_mulo_1 (a, b);
+}
+static inline vec_int4
+spu_mulo (vec_short8 a, short b)
+{
+  return __builtin_spu_mulo_2 (a, b);
+}
+static inline vec_uint4
+spu_mulo (vec_ushort8 a, unsigned short b)
+{
+  return __builtin_spu_mulo_3 (a, b);
+}
+static inline vec_float4
+spu_nmsub (vec_float4 a, vec_float4 b, vec_float4 c)
+{
+  return __builtin_spu_nmsub_0 (a, b, c);
+}
+static inline vec_double2
+spu_nmsub (vec_double2 a, vec_double2 b, vec_double2 c)
+{
+  return __builtin_spu_nmsub_1 (a, b, c);
+}
+static inline vec_ushort8
+spu_sub (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_sub_0 (a, b);
+}
+static inline vec_short8
+spu_sub (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_sub_1 (a, b);
+}
+static inline vec_uint4
+spu_sub (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_sub_2 (a, b);
+}
+static inline vec_int4
+spu_sub (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_sub_3 (a, b);
+}
+static inline vec_float4
+spu_sub (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_sub_4 (a, b);
+}
+static inline vec_double2
+spu_sub (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_sub_5 (a, b);
+}
+static inline vec_ushort8
+spu_sub (unsigned short a, vec_ushort8 b)
+{
+  return __builtin_spu_sub_6 (a, b);
+}
+static inline vec_short8
+spu_sub (short a, vec_short8 b)
+{
+  return __builtin_spu_sub_7 (a, b);
+}
+static inline vec_uint4
+spu_sub (unsigned int a, vec_uint4 b)
+{
+  return __builtin_spu_sub_8 (a, b);
+}
+static inline vec_int4
+spu_sub (int a, vec_int4 b)
+{
+  return __builtin_spu_sub_9 (a, b);
+}
+static inline vec_uint4
+spu_subx (vec_uint4 a, vec_uint4 b, vec_uint4 c)
+{
+  return __builtin_spu_subx_0 (a, b, c);
+}
+static inline vec_int4
+spu_subx (vec_int4 a, vec_int4 b, vec_int4 c)
+{
+  return __builtin_spu_subx_1 (a, b, c);
+}
+static inline vec_uint4
+spu_genb (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_genb_0 (a, b);
+}
+static inline vec_int4
+spu_genb (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_genb_1 (a, b);
+}
+static inline vec_uint4
+spu_genbx (vec_uint4 a, vec_uint4 b, vec_uint4 c)
+{
+  return __builtin_spu_genbx_0 (a, b, c);
+}
+static inline vec_int4
+spu_genbx (vec_int4 a, vec_int4 b, vec_int4 c)
+{
+  return __builtin_spu_genbx_1 (a, b, c);
+}
+static inline vec_uchar16
+spu_cmpeq (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_cmpeq_0 (a, b);
+}
+static inline vec_uchar16
+spu_cmpeq (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_cmpeq_1 (a, b);
+}
+static inline vec_ushort8
+spu_cmpeq (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_cmpeq_2 (a, b);
+}
+static inline vec_ushort8
+spu_cmpeq (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_cmpeq_3 (a, b);
+}
+static inline vec_uint4
+spu_cmpeq (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_cmpeq_4 (a, b);
+}
+static inline vec_uint4
+spu_cmpeq (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_cmpeq_5 (a, b);
+}
+static inline vec_uint4
+spu_cmpeq (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_cmpeq_6 (a, b);
+}
+static inline vec_uchar16
+spu_cmpeq (vec_uchar16 a, unsigned char b)
+{
+  return __builtin_spu_cmpeq_7 (a, b);
+}
+static inline vec_uchar16
+spu_cmpeq (vec_char16 a, signed char b)
+{
+  return __builtin_spu_cmpeq_8 (a, b);
+}
+static inline vec_ushort8
+spu_cmpeq (vec_ushort8 a, unsigned short b)
+{
+  return __builtin_spu_cmpeq_9 (a, b);
+}
+static inline vec_ushort8
+spu_cmpeq (vec_short8 a, short b)
+{
+  return __builtin_spu_cmpeq_10 (a, b);
+}
+static inline vec_uint4
+spu_cmpeq (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_cmpeq_11 (a, b);
+}
+static inline vec_uint4
+spu_cmpeq (vec_int4 a, int b)
+{
+  return __builtin_spu_cmpeq_12 (a, b);
+}
+static inline vec_uchar16
+spu_cmpgt (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_cmpgt_0 (a, b);
+}
+static inline vec_uchar16
+spu_cmpgt (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_cmpgt_1 (a, b);
+}
+static inline vec_ushort8
+spu_cmpgt (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_cmpgt_2 (a, b);
+}
+static inline vec_ushort8
+spu_cmpgt (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_cmpgt_3 (a, b);
+}
+static inline vec_uint4
+spu_cmpgt (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_cmpgt_4 (a, b);
+}
+static inline vec_uint4
+spu_cmpgt (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_cmpgt_5 (a, b);
+}
+static inline vec_uint4
+spu_cmpgt (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_cmpgt_6 (a, b);
+}
+static inline vec_uchar16
+spu_cmpgt (vec_uchar16 a, unsigned char b)
+{
+  return __builtin_spu_cmpgt_7 (a, b);
+}
+static inline vec_uchar16
+spu_cmpgt (vec_char16 a, signed char b)
+{
+  return __builtin_spu_cmpgt_8 (a, b);
+}
+static inline vec_ushort8
+spu_cmpgt (vec_ushort8 a, unsigned short b)
+{
+  return __builtin_spu_cmpgt_9 (a, b);
+}
+static inline vec_ushort8
+spu_cmpgt (vec_short8 a, short b)
+{
+  return __builtin_spu_cmpgt_10 (a, b);
+}
+static inline vec_uint4
+spu_cmpgt (vec_int4 a, int b)
+{
+  return __builtin_spu_cmpgt_11 (a, b);
+}
+static inline vec_uint4
+spu_cmpgt (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_cmpgt_12 (a, b);
+}
+static inline void
+spu_hcmpeq (int a, int b)
+{
+  return __builtin_spu_hcmpeq_0 (a, b);
+}
+static inline void
+spu_hcmpeq (unsigned int a, unsigned int b)
+{
+  return __builtin_spu_hcmpeq_1 (a, b);
+}
+static inline void
+spu_hcmpgt (int a, int b)
+{
+  return __builtin_spu_hcmpgt_0 (a, b);
+}
+static inline void
+spu_hcmpgt (unsigned int a, unsigned int b)
+{
+  return __builtin_spu_hcmpgt_1 (a, b);
+}
+static inline vec_uchar16
+spu_cntb (vec_char16 a)
+{
+  return __builtin_spu_cntb_0 (a);
+}
+static inline vec_uchar16
+spu_cntb (vec_uchar16 a)
+{
+  return __builtin_spu_cntb_1 (a);
+}
+static inline vec_uint4
+spu_cntlz (vec_int4 a)
+{
+  return __builtin_spu_cntlz_0 (a);
+}
+static inline vec_uint4
+spu_cntlz (vec_uint4 a)
+{
+  return __builtin_spu_cntlz_1 (a);
+}
+static inline vec_uint4
+spu_cntlz (vec_float4 a)
+{
+  return __builtin_spu_cntlz_2 (a);
+}
+static inline vec_uint4
+spu_gather (vec_int4 a)
+{
+  return __builtin_spu_gather_0 (a);
+}
+static inline vec_uint4
+spu_gather (vec_uint4 a)
+{
+  return __builtin_spu_gather_1 (a);
+}
+static inline vec_uint4
+spu_gather (vec_short8 a)
+{
+  return __builtin_spu_gather_2 (a);
+}
+static inline vec_uint4
+spu_gather (vec_ushort8 a)
+{
+  return __builtin_spu_gather_3 (a);
+}
+static inline vec_uint4
+spu_gather (vec_char16 a)
+{
+  return __builtin_spu_gather_4 (a);
+}
+static inline vec_uint4
+spu_gather (vec_uchar16 a)
+{
+  return __builtin_spu_gather_5 (a);
+}
+static inline vec_uint4
+spu_gather (vec_float4 a)
+{
+  return __builtin_spu_gather_6 (a);
+}
+static inline vec_uchar16
+spu_maskb (unsigned short a)
+{
+  return __builtin_spu_maskb_0 (a);
+}
+static inline vec_uchar16
+spu_maskb (short a)
+{
+  return __builtin_spu_maskb_1 (a);
+}
+static inline vec_uchar16
+spu_maskb (unsigned int a)
+{
+  return __builtin_spu_maskb_2 (a);
+}
+static inline vec_uchar16
+spu_maskb (int a)
+{
+  return __builtin_spu_maskb_3 (a);
+}
+static inline vec_ushort8
+spu_maskh (unsigned char a)
+{
+  return __builtin_spu_maskh_0 (a);
+}
+static inline vec_ushort8
+spu_maskh (signed char a)
+{
+  return __builtin_spu_maskh_1 (a);
+}
+static inline vec_ushort8
+spu_maskh (char a)
+{
+  return __builtin_spu_maskh_1 (a);
+}
+static inline vec_ushort8
+spu_maskh (unsigned short a)
+{
+  return __builtin_spu_maskh_2 (a);
+}
+static inline vec_ushort8
+spu_maskh (short a)
+{
+  return __builtin_spu_maskh_3 (a);
+}
+static inline vec_ushort8
+spu_maskh (unsigned int a)
+{
+  return __builtin_spu_maskh_4 (a);
+}
+static inline vec_ushort8
+spu_maskh (int a)
+{
+  return __builtin_spu_maskh_5 (a);
+}
+static inline vec_uint4
+spu_maskw (unsigned char a)
+{
+  return __builtin_spu_maskw_0 (a);
+}
+static inline vec_uint4
+spu_maskw (signed char a)
+{
+  return __builtin_spu_maskw_1 (a);
+}
+static inline vec_uint4
+spu_maskw (char a)
+{
+  return __builtin_spu_maskw_1 (a);
+}
+static inline vec_uint4
+spu_maskw (unsigned short a)
+{
+  return __builtin_spu_maskw_2 (a);
+}
+static inline vec_uint4
+spu_maskw (short a)
+{
+  return __builtin_spu_maskw_3 (a);
+}
+static inline vec_uint4
+spu_maskw (unsigned int a)
+{
+  return __builtin_spu_maskw_4 (a);
+}
+static inline vec_uint4
+spu_maskw (int a)
+{
+  return __builtin_spu_maskw_5 (a);
+}
+static inline vec_llong2
+spu_sel (vec_llong2 a, vec_llong2 b, vec_ullong2 c)
+{
+  return __builtin_spu_sel_0 (a, b, c);
+}
+static inline vec_ullong2
+spu_sel (vec_ullong2 a, vec_ullong2 b, vec_ullong2 c)
+{
+  return __builtin_spu_sel_1 (a, b, c);
+}
+static inline vec_int4
+spu_sel (vec_int4 a, vec_int4 b, vec_uint4 c)
+{
+  return __builtin_spu_sel_2 (a, b, c);
+}
+static inline vec_uint4
+spu_sel (vec_uint4 a, vec_uint4 b, vec_uint4 c)
+{
+  return __builtin_spu_sel_3 (a, b, c);
+}
+static inline vec_short8
+spu_sel (vec_short8 a, vec_short8 b, vec_ushort8 c)
+{
+  return __builtin_spu_sel_4 (a, b, c);
+}
+static inline vec_ushort8
+spu_sel (vec_ushort8 a, vec_ushort8 b, vec_ushort8 c)
+{
+  return __builtin_spu_sel_5 (a, b, c);
+}
+static inline vec_char16
+spu_sel (vec_char16 a, vec_char16 b, vec_uchar16 c)
+{
+  return __builtin_spu_sel_6 (a, b, c);
+}
+static inline vec_uchar16
+spu_sel (vec_uchar16 a, vec_uchar16 b, vec_uchar16 c)
+{
+  return __builtin_spu_sel_7 (a, b, c);
+}
+static inline vec_float4
+spu_sel (vec_float4 a, vec_float4 b, vec_uint4 c)
+{
+  return __builtin_spu_sel_8 (a, b, c);
+}
+static inline vec_double2
+spu_sel (vec_double2 a, vec_double2 b, vec_ullong2 c)
+{
+  return __builtin_spu_sel_9 (a, b, c);
+}
+static inline vec_uchar16
+spu_shuffle (vec_uchar16 a, vec_uchar16 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_0 (a, b, c);
+}
+static inline vec_char16
+spu_shuffle (vec_char16 a, vec_char16 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_1 (a, b, c);
+}
+static inline vec_ushort8
+spu_shuffle (vec_ushort8 a, vec_ushort8 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_2 (a, b, c);
+}
+static inline vec_short8
+spu_shuffle (vec_short8 a, vec_short8 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_3 (a, b, c);
+}
+static inline vec_uint4
+spu_shuffle (vec_uint4 a, vec_uint4 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_4 (a, b, c);
+}
+static inline vec_int4
+spu_shuffle (vec_int4 a, vec_int4 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_5 (a, b, c);
+}
+static inline vec_ullong2
+spu_shuffle (vec_ullong2 a, vec_ullong2 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_6 (a, b, c);
+}
+static inline vec_llong2
+spu_shuffle (vec_llong2 a, vec_llong2 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_7 (a, b, c);
+}
+static inline vec_float4
+spu_shuffle (vec_float4 a, vec_float4 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_8 (a, b, c);
+}
+static inline vec_double2
+spu_shuffle (vec_double2 a, vec_double2 b, vec_uchar16 c)
+{
+  return __builtin_spu_shuffle_9 (a, b, c);
+}
+static inline vec_uchar16
+spu_and (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_and_0 (a, b);
+}
+static inline vec_char16
+spu_and (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_and_1 (a, b);
+}
+static inline vec_ushort8
+spu_and (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_and_2 (a, b);
+}
+static inline vec_short8
+spu_and (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_and_3 (a, b);
+}
+static inline vec_uint4
+spu_and (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_and_4 (a, b);
+}
+static inline vec_int4
+spu_and (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_and_5 (a, b);
+}
+static inline vec_ullong2
+spu_and (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_and_6 (a, b);
+}
+static inline vec_llong2
+spu_and (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_and_7 (a, b);
+}
+static inline vec_float4
+spu_and (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_and_8 (a, b);
+}
+static inline vec_double2
+spu_and (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_and_9 (a, b);
+}
+static inline vec_uchar16
+spu_and (vec_uchar16 a, unsigned char b)
+{
+  return __builtin_spu_and_10 (a, b);
+}
+static inline vec_char16
+spu_and (vec_char16 a, signed char b)
+{
+  return __builtin_spu_and_11 (a, b);
+}
+static inline vec_ushort8
+spu_and (vec_ushort8 a, unsigned short b)
+{
+  return __builtin_spu_and_12 (a, b);
+}
+static inline vec_short8
+spu_and (vec_short8 a, short b)
+{
+  return __builtin_spu_and_13 (a, b);
+}
+static inline vec_uint4
+spu_and (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_and_14 (a, b);
+}
+static inline vec_int4
+spu_and (vec_int4 a, int b)
+{
+  return __builtin_spu_and_15 (a, b);
+}
+static inline vec_llong2
+spu_andc (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_andc_0 (a, b);
+}
+static inline vec_ullong2
+spu_andc (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_andc_1 (a, b);
+}
+static inline vec_int4
+spu_andc (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_andc_2 (a, b);
+}
+static inline vec_uint4
+spu_andc (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_andc_3 (a, b);
+}
+static inline vec_short8
+spu_andc (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_andc_4 (a, b);
+}
+static inline vec_ushort8
+spu_andc (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_andc_5 (a, b);
+}
+static inline vec_char16
+spu_andc (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_andc_6 (a, b);
+}
+static inline vec_uchar16
+spu_andc (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_andc_7 (a, b);
+}
+static inline vec_float4
+spu_andc (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_andc_8 (a, b);
+}
+static inline vec_double2
+spu_andc (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_andc_9 (a, b);
+}
+static inline vec_llong2
+spu_eqv (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_eqv_0 (a, b);
+}
+static inline vec_ullong2
+spu_eqv (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_eqv_1 (a, b);
+}
+static inline vec_int4
+spu_eqv (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_eqv_2 (a, b);
+}
+static inline vec_uint4
+spu_eqv (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_eqv_3 (a, b);
+}
+static inline vec_short8
+spu_eqv (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_eqv_4 (a, b);
+}
+static inline vec_ushort8
+spu_eqv (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_eqv_5 (a, b);
+}
+static inline vec_char16
+spu_eqv (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_eqv_6 (a, b);
+}
+static inline vec_uchar16
+spu_eqv (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_eqv_7 (a, b);
+}
+static inline vec_float4
+spu_eqv (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_eqv_8 (a, b);
+}
+static inline vec_double2
+spu_eqv (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_eqv_9 (a, b);
+}
+static inline vec_llong2
+spu_nand (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_nand_0 (a, b);
+}
+static inline vec_ullong2
+spu_nand (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_nand_1 (a, b);
+}
+static inline vec_int4
+spu_nand (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_nand_2 (a, b);
+}
+static inline vec_uint4
+spu_nand (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_nand_3 (a, b);
+}
+static inline vec_short8
+spu_nand (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_nand_4 (a, b);
+}
+static inline vec_ushort8
+spu_nand (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_nand_5 (a, b);
+}
+static inline vec_char16
+spu_nand (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_nand_6 (a, b);
+}
+static inline vec_uchar16
+spu_nand (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_nand_7 (a, b);
+}
+static inline vec_float4
+spu_nand (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_nand_8 (a, b);
+}
+static inline vec_double2
+spu_nand (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_nand_9 (a, b);
+}
+static inline vec_llong2
+spu_nor (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_nor_0 (a, b);
+}
+static inline vec_ullong2
+spu_nor (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_nor_1 (a, b);
+}
+static inline vec_int4
+spu_nor (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_nor_2 (a, b);
+}
+static inline vec_uint4
+spu_nor (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_nor_3 (a, b);
+}
+static inline vec_short8
+spu_nor (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_nor_4 (a, b);
+}
+static inline vec_ushort8
+spu_nor (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_nor_5 (a, b);
+}
+static inline vec_char16
+spu_nor (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_nor_6 (a, b);
+}
+static inline vec_uchar16
+spu_nor (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_nor_7 (a, b);
+}
+static inline vec_float4
+spu_nor (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_nor_8 (a, b);
+}
+static inline vec_double2
+spu_nor (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_nor_9 (a, b);
+}
+static inline vec_uchar16
+spu_or (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_or_0 (a, b);
+}
+static inline vec_char16
+spu_or (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_or_1 (a, b);
+}
+static inline vec_ushort8
+spu_or (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_or_2 (a, b);
+}
+static inline vec_short8
+spu_or (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_or_3 (a, b);
+}
+static inline vec_uint4
+spu_or (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_or_4 (a, b);
+}
+static inline vec_int4
+spu_or (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_or_5 (a, b);
+}
+static inline vec_ullong2
+spu_or (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_or_6 (a, b);
+}
+static inline vec_llong2
+spu_or (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_or_7 (a, b);
+}
+static inline vec_float4
+spu_or (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_or_8 (a, b);
+}
+static inline vec_double2
+spu_or (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_or_9 (a, b);
+}
+static inline vec_uchar16
+spu_or (vec_uchar16 a, unsigned char b)
+{
+  return __builtin_spu_or_10 (a, b);
+}
+static inline vec_char16
+spu_or (vec_char16 a, signed char b)
+{
+  return __builtin_spu_or_11 (a, b);
+}
+static inline vec_ushort8
+spu_or (vec_ushort8 a, unsigned short b)
+{
+  return __builtin_spu_or_12 (a, b);
+}
+static inline vec_short8
+spu_or (vec_short8 a, short b)
+{
+  return __builtin_spu_or_13 (a, b);
+}
+static inline vec_uint4
+spu_or (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_or_14 (a, b);
+}
+static inline vec_int4
+spu_or (vec_int4 a, int b)
+{
+  return __builtin_spu_or_15 (a, b);
+}
+static inline vec_llong2
+spu_orc (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_orc_0 (a, b);
+}
+static inline vec_ullong2
+spu_orc (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_orc_1 (a, b);
+}
+static inline vec_int4
+spu_orc (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_orc_2 (a, b);
+}
+static inline vec_uint4
+spu_orc (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_orc_3 (a, b);
+}
+static inline vec_short8
+spu_orc (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_orc_4 (a, b);
+}
+static inline vec_ushort8
+spu_orc (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_orc_5 (a, b);
+}
+static inline vec_char16
+spu_orc (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_orc_6 (a, b);
+}
+static inline vec_uchar16
+spu_orc (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_orc_7 (a, b);
+}
+static inline vec_float4
+spu_orc (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_orc_8 (a, b);
+}
+static inline vec_double2
+spu_orc (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_orc_9 (a, b);
+}
+static inline vec_int4
+spu_orx (vec_int4 a)
+{
+  return __builtin_spu_orx_0 (a);
+}
+static inline vec_uint4
+spu_orx (vec_uint4 a)
+{
+  return __builtin_spu_orx_1 (a);
+}
+static inline vec_uchar16
+spu_xor (vec_uchar16 a, vec_uchar16 b)
+{
+  return __builtin_spu_xor_0 (a, b);
+}
+static inline vec_char16
+spu_xor (vec_char16 a, vec_char16 b)
+{
+  return __builtin_spu_xor_1 (a, b);
+}
+static inline vec_ushort8
+spu_xor (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_xor_2 (a, b);
+}
+static inline vec_short8
+spu_xor (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_xor_3 (a, b);
+}
+static inline vec_uint4
+spu_xor (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_xor_4 (a, b);
+}
+static inline vec_int4
+spu_xor (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_xor_5 (a, b);
+}
+static inline vec_ullong2
+spu_xor (vec_ullong2 a, vec_ullong2 b)
+{
+  return __builtin_spu_xor_6 (a, b);
+}
+static inline vec_llong2
+spu_xor (vec_llong2 a, vec_llong2 b)
+{
+  return __builtin_spu_xor_7 (a, b);
+}
+static inline vec_float4
+spu_xor (vec_float4 a, vec_float4 b)
+{
+  return __builtin_spu_xor_8 (a, b);
+}
+static inline vec_double2
+spu_xor (vec_double2 a, vec_double2 b)
+{
+  return __builtin_spu_xor_9 (a, b);
+}
+static inline vec_uchar16
+spu_xor (vec_uchar16 a, unsigned char b)
+{
+  return __builtin_spu_xor_10 (a, b);
+}
+static inline vec_char16
+spu_xor (vec_char16 a, signed char b)
+{
+  return __builtin_spu_xor_11 (a, b);
+}
+static inline vec_ushort8
+spu_xor (vec_ushort8 a, unsigned short b)
+{
+  return __builtin_spu_xor_12 (a, b);
+}
+static inline vec_short8
+spu_xor (vec_short8 a, short b)
+{
+  return __builtin_spu_xor_13 (a, b);
+}
+static inline vec_uint4
+spu_xor (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_xor_14 (a, b);
+}
+static inline vec_int4
+spu_xor (vec_int4 a, int b)
+{
+  return __builtin_spu_xor_15 (a, b);
+}
+static inline vec_ushort8
+spu_rl (vec_ushort8 a, vec_short8 b)
+{
+  return __builtin_spu_rl_0 (a, b);
+}
+static inline vec_short8
+spu_rl (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_rl_1 (a, b);
+}
+static inline vec_uint4
+spu_rl (vec_uint4 a, vec_int4 b)
+{
+  return __builtin_spu_rl_2 (a, b);
+}
+static inline vec_int4
+spu_rl (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_rl_3 (a, b);
+}
+static inline vec_ushort8
+spu_rl (vec_ushort8 a, short b)
+{
+  return __builtin_spu_rl_4 (a, b);
+}
+static inline vec_short8
+spu_rl (vec_short8 a, short b)
+{
+  return __builtin_spu_rl_5 (a, b);
+}
+static inline vec_uint4
+spu_rl (vec_uint4 a, int b)
+{
+  return __builtin_spu_rl_6 (a, b);
+}
+static inline vec_int4
+spu_rl (vec_int4 a, int b)
+{
+  return __builtin_spu_rl_7 (a, b);
+}
+static inline vec_uchar16
+spu_rlqw (vec_uchar16 a, int b)
+{
+  return __builtin_spu_rlqw_0 (a, b);
+}
+static inline vec_char16
+spu_rlqw (vec_char16 a, int b)
+{
+  return __builtin_spu_rlqw_1 (a, b);
+}
+static inline vec_ushort8
+spu_rlqw (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlqw_2 (a, b);
+}
+static inline vec_short8
+spu_rlqw (vec_short8 a, int b)
+{
+  return __builtin_spu_rlqw_3 (a, b);
+}
+static inline vec_uint4
+spu_rlqw (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlqw_4 (a, b);
+}
+static inline vec_int4
+spu_rlqw (vec_int4 a, int b)
+{
+  return __builtin_spu_rlqw_5 (a, b);
+}
+static inline vec_ullong2
+spu_rlqw (vec_ullong2 a, int b)
+{
+  return __builtin_spu_rlqw_6 (a, b);
+}
+static inline vec_llong2
+spu_rlqw (vec_llong2 a, int b)
+{
+  return __builtin_spu_rlqw_7 (a, b);
+}
+static inline vec_float4
+spu_rlqw (vec_float4 a, int b)
+{
+  return __builtin_spu_rlqw_8 (a, b);
+}
+static inline vec_double2
+spu_rlqw (vec_double2 a, int b)
+{
+  return __builtin_spu_rlqw_9 (a, b);
+}
+static inline vec_uchar16
+spu_rlqwbyte (vec_uchar16 a, int b)
+{
+  return __builtin_spu_rlqwbyte_0 (a, b);
+}
+static inline vec_char16
+spu_rlqwbyte (vec_char16 a, int b)
+{
+  return __builtin_spu_rlqwbyte_1 (a, b);
+}
+static inline vec_ushort8
+spu_rlqwbyte (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlqwbyte_2 (a, b);
+}
+static inline vec_short8
+spu_rlqwbyte (vec_short8 a, int b)
+{
+  return __builtin_spu_rlqwbyte_3 (a, b);
+}
+static inline vec_uint4
+spu_rlqwbyte (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlqwbyte_4 (a, b);
+}
+static inline vec_int4
+spu_rlqwbyte (vec_int4 a, int b)
+{
+  return __builtin_spu_rlqwbyte_5 (a, b);
+}
+static inline vec_ullong2
+spu_rlqwbyte (vec_ullong2 a, int b)
+{
+  return __builtin_spu_rlqwbyte_6 (a, b);
+}
+static inline vec_llong2
+spu_rlqwbyte (vec_llong2 a, int b)
+{
+  return __builtin_spu_rlqwbyte_7 (a, b);
+}
+static inline vec_float4
+spu_rlqwbyte (vec_float4 a, int b)
+{
+  return __builtin_spu_rlqwbyte_8 (a, b);
+}
+static inline vec_double2
+spu_rlqwbyte (vec_double2 a, int b)
+{
+  return __builtin_spu_rlqwbyte_9 (a, b);
+}
+static inline vec_uchar16
+spu_rlqwbytebc (vec_uchar16 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_0 (a, b);
+}
+static inline vec_char16
+spu_rlqwbytebc (vec_char16 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_1 (a, b);
+}
+static inline vec_ushort8
+spu_rlqwbytebc (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_2 (a, b);
+}
+static inline vec_short8
+spu_rlqwbytebc (vec_short8 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_3 (a, b);
+}
+static inline vec_uint4
+spu_rlqwbytebc (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_4 (a, b);
+}
+static inline vec_int4
+spu_rlqwbytebc (vec_int4 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_5 (a, b);
+}
+static inline vec_ullong2
+spu_rlqwbytebc (vec_ullong2 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_6 (a, b);
+}
+static inline vec_llong2
+spu_rlqwbytebc (vec_llong2 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_7 (a, b);
+}
+static inline vec_float4
+spu_rlqwbytebc (vec_float4 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_8 (a, b);
+}
+static inline vec_double2
+spu_rlqwbytebc (vec_double2 a, int b)
+{
+  return __builtin_spu_rlqwbytebc_9 (a, b);
+}
+static inline vec_ushort8
+spu_rlmask (vec_ushort8 a, vec_short8 b)
+{
+  return __builtin_spu_rlmask_0 (a, b);
+}
+static inline vec_short8
+spu_rlmask (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_rlmask_1 (a, b);
+}
+static inline vec_uint4
+spu_rlmask (vec_uint4 a, vec_int4 b)
+{
+  return __builtin_spu_rlmask_2 (a, b);
+}
+static inline vec_int4
+spu_rlmask (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_rlmask_3 (a, b);
+}
+static inline vec_ushort8
+spu_rlmask (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlmask_4 (a, b);
+}
+static inline vec_short8
+spu_rlmask (vec_short8 a, int b)
+{
+  return __builtin_spu_rlmask_5 (a, b);
+}
+static inline vec_uint4
+spu_rlmask (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlmask_6 (a, b);
+}
+static inline vec_int4
+spu_rlmask (vec_int4 a, int b)
+{
+  return __builtin_spu_rlmask_7 (a, b);
+}
+static inline vec_ushort8
+spu_rlmaska (vec_ushort8 a, vec_short8 b)
+{
+  return __builtin_spu_rlmaska_0 (a, b);
+}
+static inline vec_short8
+spu_rlmaska (vec_short8 a, vec_short8 b)
+{
+  return __builtin_spu_rlmaska_1 (a, b);
+}
+static inline vec_uint4
+spu_rlmaska (vec_uint4 a, vec_int4 b)
+{
+  return __builtin_spu_rlmaska_2 (a, b);
+}
+static inline vec_int4
+spu_rlmaska (vec_int4 a, vec_int4 b)
+{
+  return __builtin_spu_rlmaska_3 (a, b);
+}
+static inline vec_ushort8
+spu_rlmaska (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlmaska_4 (a, b);
+}
+static inline vec_short8
+spu_rlmaska (vec_short8 a, int b)
+{
+  return __builtin_spu_rlmaska_5 (a, b);
+}
+static inline vec_uint4
+spu_rlmaska (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlmaska_6 (a, b);
+}
+static inline vec_int4
+spu_rlmaska (vec_int4 a, int b)
+{
+  return __builtin_spu_rlmaska_7 (a, b);
+}
+static inline vec_uchar16
+spu_rlmaskqw (vec_uchar16 a, int b)
+{
+  return __builtin_spu_rlmaskqw_0 (a, b);
+}
+static inline vec_char16
+spu_rlmaskqw (vec_char16 a, int b)
+{
+  return __builtin_spu_rlmaskqw_1 (a, b);
+}
+static inline vec_ushort8
+spu_rlmaskqw (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlmaskqw_2 (a, b);
+}
+static inline vec_short8
+spu_rlmaskqw (vec_short8 a, int b)
+{
+  return __builtin_spu_rlmaskqw_3 (a, b);
+}
+static inline vec_uint4
+spu_rlmaskqw (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlmaskqw_4 (a, b);
+}
+static inline vec_int4
+spu_rlmaskqw (vec_int4 a, int b)
+{
+  return __builtin_spu_rlmaskqw_5 (a, b);
+}
+static inline vec_ullong2
+spu_rlmaskqw (vec_ullong2 a, int b)
+{
+  return __builtin_spu_rlmaskqw_6 (a, b);
+}
+static inline vec_llong2
+spu_rlmaskqw (vec_llong2 a, int b)
+{
+  return __builtin_spu_rlmaskqw_7 (a, b);
+}
+static inline vec_float4
+spu_rlmaskqw (vec_float4 a, int b)
+{
+  return __builtin_spu_rlmaskqw_8 (a, b);
+}
+static inline vec_double2
+spu_rlmaskqw (vec_double2 a, int b)
+{
+  return __builtin_spu_rlmaskqw_9 (a, b);
+}
+static inline vec_uchar16
+spu_rlmaskqwbyte (vec_uchar16 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_0 (a, b);
+}
+static inline vec_char16
+spu_rlmaskqwbyte (vec_char16 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_1 (a, b);
+}
+static inline vec_ushort8
+spu_rlmaskqwbyte (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_2 (a, b);
+}
+static inline vec_short8
+spu_rlmaskqwbyte (vec_short8 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_3 (a, b);
+}
+static inline vec_uint4
+spu_rlmaskqwbyte (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_4 (a, b);
+}
+static inline vec_int4
+spu_rlmaskqwbyte (vec_int4 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_5 (a, b);
+}
+static inline vec_ullong2
+spu_rlmaskqwbyte (vec_ullong2 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_6 (a, b);
+}
+static inline vec_llong2
+spu_rlmaskqwbyte (vec_llong2 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_7 (a, b);
+}
+static inline vec_float4
+spu_rlmaskqwbyte (vec_float4 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_8 (a, b);
+}
+static inline vec_double2
+spu_rlmaskqwbyte (vec_double2 a, int b)
+{
+  return __builtin_spu_rlmaskqwbyte_9 (a, b);
+}
+static inline vec_uchar16
+spu_rlmaskqwbytebc (vec_uchar16 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_0 (a, b);
+}
+static inline vec_char16
+spu_rlmaskqwbytebc (vec_char16 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_1 (a, b);
+}
+static inline vec_ushort8
+spu_rlmaskqwbytebc (vec_ushort8 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_2 (a, b);
+}
+static inline vec_short8
+spu_rlmaskqwbytebc (vec_short8 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_3 (a, b);
+}
+static inline vec_uint4
+spu_rlmaskqwbytebc (vec_uint4 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_4 (a, b);
+}
+static inline vec_int4
+spu_rlmaskqwbytebc (vec_int4 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_5 (a, b);
+}
+static inline vec_ullong2
+spu_rlmaskqwbytebc (vec_ullong2 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_6 (a, b);
+}
+static inline vec_llong2
+spu_rlmaskqwbytebc (vec_llong2 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_7 (a, b);
+}
+static inline vec_float4
+spu_rlmaskqwbytebc (vec_float4 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_8 (a, b);
+}
+static inline vec_double2
+spu_rlmaskqwbytebc (vec_double2 a, int b)
+{
+  return __builtin_spu_rlmaskqwbytebc_9 (a, b);
+}
+static inline vec_ushort8
+spu_sl (vec_ushort8 a, vec_ushort8 b)
+{
+  return __builtin_spu_sl_0 (a, b);
+}
+static inline vec_short8
+spu_sl (vec_short8 a, vec_ushort8 b)
+{
+  return __builtin_spu_sl_1 (a, b);
+}
+static inline vec_uint4
+spu_sl (vec_uint4 a, vec_uint4 b)
+{
+  return __builtin_spu_sl_2 (a, b);
+}
+static inline vec_int4
+spu_sl (vec_int4 a, vec_uint4 b)
+{
+  return __builtin_spu_sl_3 (a, b);
+}
+static inline vec_ushort8
+spu_sl (vec_ushort8 a, unsigned int b)
+{
+  return __builtin_spu_sl_4 (a, b);
+}
+static inline vec_short8
+spu_sl (vec_short8 a, unsigned int b)
+{
+  return __builtin_spu_sl_5 (a, b);
+}
+static inline vec_uint4
+spu_sl (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_sl_6 (a, b);
+}
+static inline vec_int4
+spu_sl (vec_int4 a, unsigned int b)
+{
+  return __builtin_spu_sl_7 (a, b);
+}
+static inline vec_llong2
+spu_slqw (vec_llong2 a, unsigned int b)
+{
+  return __builtin_spu_slqw_0 (a, b);
+}
+static inline vec_ullong2
+spu_slqw (vec_ullong2 a, unsigned int b)
+{
+  return __builtin_spu_slqw_1 (a, b);
+}
+static inline vec_int4
+spu_slqw (vec_int4 a, unsigned int b)
+{
+  return __builtin_spu_slqw_2 (a, b);
+}
+static inline vec_uint4
+spu_slqw (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_slqw_3 (a, b);
+}
+static inline vec_short8
+spu_slqw (vec_short8 a, unsigned int b)
+{
+  return __builtin_spu_slqw_4 (a, b);
+}
+static inline vec_ushort8
+spu_slqw (vec_ushort8 a, unsigned int b)
+{
+  return __builtin_spu_slqw_5 (a, b);
+}
+static inline vec_char16
+spu_slqw (vec_char16 a, unsigned int b)
+{
+  return __builtin_spu_slqw_6 (a, b);
+}
+static inline vec_uchar16
+spu_slqw (vec_uchar16 a, unsigned int b)
+{
+  return __builtin_spu_slqw_7 (a, b);
+}
+static inline vec_float4
+spu_slqw (vec_float4 a, unsigned int b)
+{
+  return __builtin_spu_slqw_8 (a, b);
+}
+static inline vec_double2
+spu_slqw (vec_double2 a, unsigned int b)
+{
+  return __builtin_spu_slqw_9 (a, b);
+}
+static inline vec_llong2
+spu_slqwbyte (vec_llong2 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_0 (a, b);
+}
+static inline vec_ullong2
+spu_slqwbyte (vec_ullong2 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_1 (a, b);
+}
+static inline vec_int4
+spu_slqwbyte (vec_int4 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_2 (a, b);
+}
+static inline vec_uint4
+spu_slqwbyte (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_3 (a, b);
+}
+static inline vec_short8
+spu_slqwbyte (vec_short8 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_4 (a, b);
+}
+static inline vec_ushort8
+spu_slqwbyte (vec_ushort8 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_5 (a, b);
+}
+static inline vec_char16
+spu_slqwbyte (vec_char16 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_6 (a, b);
+}
+static inline vec_uchar16
+spu_slqwbyte (vec_uchar16 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_7 (a, b);
+}
+static inline vec_float4
+spu_slqwbyte (vec_float4 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_8 (a, b);
+}
+static inline vec_double2
+spu_slqwbyte (vec_double2 a, unsigned int b)
+{
+  return __builtin_spu_slqwbyte_9 (a, b);
+}
+static inline vec_llong2
+spu_slqwbytebc (vec_llong2 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_0 (a, b);
+}
+static inline vec_ullong2
+spu_slqwbytebc (vec_ullong2 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_1 (a, b);
+}
+static inline vec_int4
+spu_slqwbytebc (vec_int4 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_2 (a, b);
+}
+static inline vec_uint4
+spu_slqwbytebc (vec_uint4 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_3 (a, b);
+}
+static inline vec_short8
+spu_slqwbytebc (vec_short8 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_4 (a, b);
+}
+static inline vec_ushort8
+spu_slqwbytebc (vec_ushort8 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_5 (a, b);
+}
+static inline vec_char16
+spu_slqwbytebc (vec_char16 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_6 (a, b);
+}
+static inline vec_uchar16
+spu_slqwbytebc (vec_uchar16 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_7 (a, b);
+}
+static inline vec_float4
+spu_slqwbytebc (vec_float4 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_8 (a, b);
+}
+static inline vec_double2
+spu_slqwbytebc (vec_double2 a, unsigned int b)
+{
+  return __builtin_spu_slqwbytebc_9 (a, b);
+}
+static inline vec_uchar16
+spu_splats (unsigned char a)
+{
+  return __builtin_spu_splats_0 (a);
+}
+static inline vec_char16
+spu_splats (signed char a)
+{
+  return __builtin_spu_splats_1 (a);
+}
+static inline vec_char16
+spu_splats (char a)
+{
+  return __builtin_spu_splats_1 (a);
+}
+static inline vec_ushort8
+spu_splats (unsigned short a)
+{
+  return __builtin_spu_splats_2 (a);
+}
+static inline vec_short8
+spu_splats (short a)
+{
+  return __builtin_spu_splats_3 (a);
+}
+static inline vec_uint4
+spu_splats (unsigned int a)
+{
+  return __builtin_spu_splats_4 (a);
+}
+static inline vec_int4
+spu_splats (int a)
+{
+  return __builtin_spu_splats_5 (a);
+}
+static inline vec_ullong2
+spu_splats (unsigned long long a)
+{
+  return __builtin_spu_splats_6 (a);
+}
+static inline vec_llong2
+spu_splats (long long a)
+{
+  return __builtin_spu_splats_7 (a);
+}
+static inline vec_float4
+spu_splats (float a)
+{
+  return __builtin_spu_splats_8 (a);
+}
+static inline vec_double2
+spu_splats (double a)
+{
+  return __builtin_spu_splats_9 (a);
+}
+static inline unsigned char
+spu_extract (vec_uchar16 a, int b)
+{
+  return __builtin_spu_extract_0 (a, b);
+}
+static inline signed char
+spu_extract (vec_char16 a, int b)
+{
+  return __builtin_spu_extract_1 (a, b);
+}
+static inline unsigned short
+spu_extract (vec_ushort8 a, int b)
+{
+  return __builtin_spu_extract_2 (a, b);
+}
+static inline short
+spu_extract (vec_short8 a, int b)
+{
+  return __builtin_spu_extract_3 (a, b);
+}
+static inline unsigned int
+spu_extract (vec_uint4 a, int b)
+{
+  return __builtin_spu_extract_4 (a, b);
+}
+static inline int
+spu_extract (vec_int4 a, int b)
+{
+  return __builtin_spu_extract_5 (a, b);
+}
+static inline unsigned long long
+spu_extract (vec_ullong2 a, int b)
+{
+  return __builtin_spu_extract_6 (a, b);
+}
+static inline long long
+spu_extract (vec_llong2 a, int b)
+{
+  return __builtin_spu_extract_7 (a, b);
+}
+static inline float
+spu_extract (vec_float4 a, int b)
+{
+  return __builtin_spu_extract_8 (a, b);
+}
+static inline double
+spu_extract (vec_double2 a, int b)
+{
+  return __builtin_spu_extract_9 (a, b);
+}
+static inline vec_uchar16
+spu_insert (unsigned char a, vec_uchar16 b, int c)
+{
+  return __builtin_spu_insert_0 (a, b, c);
+}
+static inline vec_char16
+spu_insert (signed char a, vec_char16 b, int c)
+{
+  return __builtin_spu_insert_1 (a, b, c);
+}
+static inline vec_ushort8
+spu_insert (unsigned short a, vec_ushort8 b, int c)
+{
+  return __builtin_spu_insert_2 (a, b, c);
+}
+static inline vec_short8
+spu_insert (short a, vec_short8 b, int c)
+{
+  return __builtin_spu_insert_3 (a, b, c);
+}
+static inline vec_uint4
+spu_insert (unsigned int a, vec_uint4 b, int c)
+{
+  return __builtin_spu_insert_4 (a, b, c);
+}
+static inline vec_int4
+spu_insert (int a, vec_int4 b, int c)
+{
+  return __builtin_spu_insert_5 (a, b, c);
+}
+static inline vec_ullong2
+spu_insert (unsigned long long a, vec_ullong2 b, int c)
+{
+  return __builtin_spu_insert_6 (a, b, c);
+}
+static inline vec_llong2
+spu_insert (long long a, vec_llong2 b, int c)
+{
+  return __builtin_spu_insert_7 (a, b, c);
+}
+static inline vec_float4
+spu_insert (float a, vec_float4 b, int c)
+{
+  return __builtin_spu_insert_8 (a, b, c);
+}
+static inline vec_double2
+spu_insert (double a, vec_double2 b, int c)
+{
+  return __builtin_spu_insert_9 (a, b, c);
+}
+static inline vec_uchar16
+spu_promote (unsigned char a, int b)
+{
+  return __builtin_spu_promote_0 (a, b);
+}
+static inline vec_char16
+spu_promote (signed char a, int b)
+{
+  return __builtin_spu_promote_1 (a, b);
+}
+static inline vec_char16
+spu_promote (char a, int b)
+{
+  return __builtin_spu_promote_1 (a, b);
+}
+static inline vec_ushort8
+spu_promote (unsigned short a, int b)
+{
+  return __builtin_spu_promote_2 (a, b);
+}
+static inline vec_short8
+spu_promote (short a, int b)
+{
+  return __builtin_spu_promote_3 (a, b);
+}
+static inline vec_uint4
+spu_promote (unsigned int a, int b)
+{
+  return __builtin_spu_promote_4 (a, b);
+}
+static inline vec_int4
+spu_promote (int a, int b)
+{
+  return __builtin_spu_promote_5 (a, b);
+}
+static inline vec_ullong2
+spu_promote (unsigned long long a, int b)
+{
+  return __builtin_spu_promote_6 (a, b);
+}
+static inline vec_llong2
+spu_promote (long long a, int b)
+{
+  return __builtin_spu_promote_7 (a, b);
+}
+static inline vec_float4
+spu_promote (float a, int b)
+{
+  return __builtin_spu_promote_8 (a, b);
+}
+static inline vec_double2
+spu_promote (double a, int b)
+{
+  return __builtin_spu_promote_9 (a, b);
+}
+#endif  /* __cplusplus */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The type checking for some of these won't be accurate but they need
+ * to be defines because of the immediate values. */
+#define spu_idisable()          __builtin_spu_idisable()
+#define spu_ienable()           __builtin_spu_ienable()
+#define spu_mfspr(imm)          si_to_uint(si_mfspr((imm)))
+#define spu_mtspr(imm, ra)      si_mtspr((imm),si_from_uint (ra))
+#define spu_mffpscr()           ((vec_uint4)si_fscrrd())
+#define spu_mtfpscr(a)          si_fscrwr((qword)a)
+#define spu_dsync()             si_dsync() 
+#define spu_stop(imm)           si_stop(imm)
+#define spu_sync()              si_sync()
+#define spu_sync_c()            si_syncc()
+#define spu_readch(imm)         si_to_uint(si_rdch((imm)))
+#define spu_readchqw(imm)       ((vec_uint4)si_rdch((imm)))
+#define spu_readchcnt(imm)      si_to_uint(si_rchcnt((imm)))
+#define spu_writech(imm, ra)    si_wrch((imm), si_from_uint(ra))
+#define spu_writechqw(imm, ra)  si_wrch((imm), (qword)(ra))
+
+/* The following functions are static and always_inline to make sure
+ * they don't show up in object files which they aren't used in.  */
+
+static __inline__ vec_float4 spu_re (vec_float4 ra) __attribute__((__always_inline__));
+static __inline__ vec_float4 spu_rsqrte (vec_float4 ra) __attribute__((__always_inline__));
+
+static __inline__ vec_float4
+spu_re (vec_float4 ra)
+{
+  return (vec_float4) si_fi ((qword) (ra), si_frest ((qword) (ra)));
+}
+static __inline__ vec_float4
+spu_rsqrte (vec_float4 ra)
+{
+  return (vec_float4) si_fi ((qword) (ra), si_frsqest ((qword) (ra)));
+}
+
+/* composite intrinsics */
+static __inline__ void spu_mfcdma32(volatile void *ls, unsigned int ea, unsigned int size, unsigned int tagid, unsigned int cmd) __attribute__((__always_inline__));
+static __inline__ void spu_mfcdma64(volatile void *ls, unsigned int eahi, unsigned int ealow, unsigned int size, unsigned int tagid, unsigned int cmd) __attribute__((__always_inline__));
+static __inline__ unsigned int spu_mfcstat(unsigned int type) __attribute__((__always_inline__));
+
+static __inline__ void
+spu_mfcdma32(volatile void *ls, unsigned int ea, unsigned int size, unsigned int tagid, unsigned int cmd)
+{
+      si_wrch(MFC_LSA,si_from_ptr(ls));
+      si_wrch(MFC_EAL,si_from_uint(ea));
+      si_wrch(MFC_Size,si_from_uint(size));
+      si_wrch(MFC_TagID,si_from_uint(tagid));
+      si_wrch(MFC_Cmd,si_from_uint(cmd));
+}
+static __inline__ void
+spu_mfcdma64(volatile void *ls, unsigned int eahi, unsigned int ealow, unsigned int size, unsigned int tagid, unsigned int cmd)
+{
+      si_wrch(MFC_LSA,si_from_ptr(ls));
+      si_wrch(MFC_EAH,si_from_uint(eahi));
+      si_wrch(MFC_EAL,si_from_uint(ealow));
+      si_wrch(MFC_Size,si_from_uint(size));
+      si_wrch(MFC_TagID,si_from_uint(tagid));
+      si_wrch(MFC_Cmd,si_from_uint(cmd));
+}
+static __inline__ unsigned int
+spu_mfcstat(unsigned int type)
+{
+      si_wrch(MFC_WrTagUpdate,si_from_uint(type));
+      return si_to_uint(si_rdch(MFC_RdTagStat));
+}
+#ifdef __cplusplus
+
+}
+#endif  /* __cplusplus */
+
+#endif /* SPUINTRIN_H */
+
diff --git a/gcc/config/spu/spu_intrinsics.h b/gcc/config/spu/spu_intrinsics.h
new file mode 100644 (file)
index 0000000..a083216
--- /dev/null
@@ -0,0 +1,75 @@
+/* Definitions of Synergistic Processing Unit (SPU). */
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source files 
+   compiled by GCC, this header file does not by itself cause  the resulting 
+   executable to be covered by the GNU General Public License.  This exception 
+   does not however invalidate any other reasons why the executable file might be 
+   covered by the GNU General Public License.  */ 
+
+#ifndef  _SPU_INTRINSICS_H
+#define _SPU_INTRINSICS_H 
+#define vec_uchar16             __vector unsigned char
+#define vec_char16              __vector   signed char
+#define vec_ushort8             __vector unsigned short
+#define vec_short8              __vector   signed short
+#define vec_uint4               __vector unsigned int
+#define vec_int4                __vector   signed int
+#define vec_ullong2             __vector unsigned long long
+#define vec_llong2              __vector   signed long long
+#define vec_float4              __vector          float
+#define vec_double2             __vector          double
+
+/* SPU Channel Defines 
+ */
+#define SPU_RdEventStat                 0
+#define SPU_WrEventMask                 1
+#define SPU_WrEventAck          2
+#define SPU_RdSigNotify1        3
+#define SPU_RdSigNotify2        4
+#define SPU_WrDec               7
+#define SPU_RdDec               8
+#define SPU_RdEventStatMask    11
+#define SPU_RdMachStat         13
+#define SPU_WrSRR0             14
+#define SPU_RdSRR0             15
+#define SPU_WrOutMbox          28 
+#define SPU_RdInMbox           29 
+#define SPU_WrOutIntrMbox      30 
+
+/* MFC Channel Defines. 
+ */
+#define MFC_WrMSSyncReq                 9
+#define MFC_RdTagMask          12
+#define MFC_LSA                        16 
+#define MFC_EAH                        17 
+#define MFC_EAL                        18 
+#define MFC_Size               19 
+#define MFC_TagID              20 
+#define MFC_Cmd                        21 
+#define MFC_WrTagMask          22 
+#define MFC_WrTagUpdate                23 
+#define MFC_RdTagStat          24 
+#define MFC_RdListStallStat    25 
+#define MFC_WrListStallAck     26 
+#define MFC_RdAtomicStat       27 
+
+#include <spu_internals.h>
+
+#endif /* _SPU_INTRINSICS_H */
diff --git a/gcc/config/spu/spu_mfcio.h b/gcc/config/spu/spu_mfcio.h
new file mode 100644 (file)
index 0000000..b0436bc
--- /dev/null
@@ -0,0 +1,270 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source files 
+   compiled by GCC, this header file does not by itself cause  the resulting 
+   executable to be covered by the GNU General Public License.  This exception 
+   does not however invalidate any other reasons why the executable file might be 
+   covered by the GNU General Public License.  */ 
+
+#ifndef __SPU_MFCIO_H__
+#define __SPU_MFCIO_H__ 1
+
+#include <spu_intrinsics.h>
+#include <stdint.h>
+
+
+/****************************************************************/
+/* DMA list element structure*/
+/****************************************************************/
+#ifdef __GNUC__
+__extension__
+#endif
+typedef struct mfc_list_element {
+  uint64_t notify       :  1;   /** Stall-and-notify bit  */
+  uint64_t reserved     : 15;
+  uint64_t size         : 16;   /** Transfer size */
+  uint64_t eal          : 32;   /** Lower word of effective address */
+} mfc_list_element_t;
+/****************************************************************/
+/* DMA max/min size definitions.                        */
+/****************************************************************/
+
+#define MFC_MIN_DMA_SIZE_SHIFT  4      /* 16 bytes */
+#define MFC_MAX_DMA_SIZE_SHIFT 14      /* 16384 bytes */
+
+#define MFC_MIN_DMA_SIZE (1 << MFC_MIN_DMA_SIZE_SHIFT)
+#define MFC_MAX_DMA_SIZE (1 << MFC_MAX_DMA_SIZE_SHIFT)
+
+#define MFC_MIN_DMA_SIZE_MASK (MFC_MIN_DMA_SIZE - 1)
+#define MFC_MAX_DMA_SIZE_MASK (MFC_MAX_DMA_SIZE - 1)
+
+#define MFC_MIN_DMA_LIST_SIZE 0x0008   /*   8 bytes */
+#define MFC_MAX_DMA_LIST_SIZE 0x4000   /* 16K bytes */
+
+/****************************************************************/
+/* MFC DMA Command flags which identify classes of operations.   */
+/****************************************************************/
+/* Note: These flags may be used in conjunction with the base command types
+  (i.e. MFC_PUT_CMD, MFC_PUTR_CMD, MFC_GET_CMD, and MFC_SNDSIG_CMD)
+  to construct the various command permutations.
+ */
+
+#define MFC_BARRIER_ENABLE    0x0001
+#define MFC_FENCE_ENABLE      0x0002
+#define MFC_LIST_ENABLE       0x0004   /* SPU Only */
+#define MFC_START_ENABLE      0x0008   /*  PU Only */
+#define MFC_RESULT_ENABLE     0x0010
+
+/****************************************************************/
+/* MFC DMA Put Commands                                 */
+/****************************************************************/
+
+#define MFC_PUT_CMD          0x0020
+#define MFC_PUTS_CMD         0x0028   /*  PU Only */
+#define MFC_PUTR_CMD         0x0030
+#define MFC_PUTF_CMD         0x0022
+#define MFC_PUTB_CMD         0x0021
+#define MFC_PUTFS_CMD        0x002A   /*  PU Only */
+#define MFC_PUTBS_CMD        0x0029   /*  PU Only */
+#define MFC_PUTRF_CMD        0x0032
+#define MFC_PUTRB_CMD        0x0031
+#define MFC_PUTL_CMD         0x0024   /* SPU Only */
+#define MFC_PUTRL_CMD        0x0034   /* SPU Only */
+#define MFC_PUTLF_CMD        0x0026   /* SPU Only */
+#define MFC_PUTLB_CMD        0x0025   /* SPU Only */
+#define MFC_PUTRLF_CMD       0x0036   /* SPU Only */
+#define MFC_PUTRLB_CMD       0x0035   /* SPU Only */
+
+/****************************************************************/
+/* MFC DMA Get Commands                                 */
+/****************************************************************/
+
+#define MFC_GET_CMD          0x0040
+#define MFC_GETS_CMD         0x0048   /*  PU Only */
+#define MFC_GETF_CMD         0x0042
+#define MFC_GETB_CMD         0x0041
+#define MFC_GETFS_CMD        0x004A   /*  PU Only */
+#define MFC_GETBS_CMD        0x0049   /*  PU Only */
+#define MFC_GETL_CMD         0x0044   /* SPU Only */
+#define MFC_GETLF_CMD        0x0046   /* SPU Only */
+#define MFC_GETLB_CMD        0x0045   /* SPU Only */
+
+/****************************************************************/
+/* MFC Synchronization Commands                           */
+/****************************************************************/
+
+#define MFC_SNDSIG_CMD       0x00A0
+#define MFC_SNDSIGB_CMD      0x00A1
+#define MFC_SNDSIGF_CMD      0x00A2
+#define MFC_BARRIER_CMD      0x00C0
+#define MFC_EIEIO_CMD        0x00C8
+#define MFC_SYNC_CMD         0x00CC
+
+/****************************************************************/
+/* MFC Atomic Commands                                 */
+/****************************************************************/
+
+#define MFC_GETLLAR_CMD      0x00D0   /* SPU Only */
+#define MFC_PUTLLC_CMD       0x00B4   /* SPU Only */
+#define MFC_PUTLLUC_CMD      0x00B0   /* SPU Only */
+#define MFC_PUTQLLUC_CMD     0x00B8   /* SPU Only */
+
+/****************************************************************/
+/* Channel Defines                                    */
+/****************************************************************/
+
+/* Events Defines for channels
+ *    0 (SPU_RdEventStat),
+ *    1 (SPU_WrEventMask), and
+ *    2 (SPU_WrEventAck).
+ */
+#define MFC_TAG_STATUS_UPDATE_EVENT         0x00000001
+#define MFC_LIST_STALL_NOTIFY_EVENT         0x00000002
+#define MFC_COMMAND_QUEUE_AVAILABLE_EVENT   0x00000008
+#define MFC_IN_MBOX_AVAILABLE_EVENT         0x00000010
+#define MFC_DECREMENTER_EVENT               0x00000020
+#define MFC_OUT_INTR_MBOX_AVAILABLE_EVENT   0x00000040
+#define MFC_OUT_MBOX_AVAILABLE_EVENT        0x00000080
+#define MFC_SIGNAL_NOTIFY_2_EVENT           0x00000100
+#define MFC_SIGNAL_NOTIFY_1_EVENT           0x00000200
+#define MFC_LLR_LOST_EVENT                  0x00000400
+#define MFC_PRIV_ATTN_EVENT                 0x00000800
+#define MFC_MULTI_SRC_SYNC_EVENT            0x00001000
+
+/* Tag Status Update defines for channel 23 (MFC_WrTagUpdate) */
+#define MFC_TAG_UPDATE_IMMEDIATE   0x0
+#define MFC_TAG_UPDATE_ANY         0x1
+#define MFC_TAG_UPDATE_ALL         0x2
+
+/* Atomic Command Status defines for channel 27 (MFC_RdAtomicStat) */
+#define MFC_PUTLLC_STATUS    0x00000001
+#define MFC_PUTLLUC_STATUS   0x00000002
+#define MFC_GETLLAR_STATUS   0x00000004
+
+
+/****************************************************************/
+/* Definitions for constructing a 32-bit command word         */
+/* including the transfer and replacement class id and the      */
+/* command opcode.                                    */
+/****************************************************************/
+#define MFC_CMD_WORD(_tid, _rid, _cmd) (((_tid)<<24)|((_rid)<<16)|(_cmd))
+
+
+/* Addressing Utilities */
+#define mfc_ea2h(ea)   (unsigned int)((unsigned long long)(ea)>>32)
+#define mfc_ea2l(ea)   (unsigned int)(ea)
+#define mfc_hl2ea(h,l)   si_to_ullong(si_selb(si_from_uint(h),\
+                                  si_rotqbyi(si_from_uint(l), -4),\
+                                  si_fsmbi(0x0f0f)))
+#define mfc_ceil128(v)   (((v) + 127) & ~127)
+
+/* MFC DMA */
+#define mfc_put(  ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUT_CMD))
+#define mfc_putf( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTF_CMD))
+#define mfc_putb( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTB_CMD))
+#define mfc_get(  ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_GET_CMD))
+#define mfc_getf( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETF_CMD))
+#define mfc_getb( ls,ea,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETB_CMD))
+
+/* MFC list DMA */
+#define mfc_putl(  ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTL_CMD))
+#define mfc_putlf( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTLF_CMD))
+#define mfc_putlb( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_PUTLB_CMD))
+#define mfc_getl(  ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETL_CMD))
+#define mfc_getlf( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETLF_CMD))
+#define mfc_getlb( ls,ea,lsa,size,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),(unsigned int)(lsa),size,tag,MFC_CMD_WORD(tid,rid,MFC_GETLB_CMD))
+
+/* MFC Atomic Update DMA */
+#define mfc_getllar( ls,ea,tid,rid)     spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128,  0,MFC_CMD_WORD(tid,rid,MFC_GETLLAR_CMD))
+#define mfc_putllc(  ls,ea,tid,rid)     spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128,  0,MFC_CMD_WORD(tid,rid,MFC_PUTLLC_CMD))
+#define mfc_putlluc( ls,ea,tid,rid)     spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128,  0,MFC_CMD_WORD(tid,rid,MFC_PUTLLUC_CMD))
+#define mfc_putqlluc(ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),128,tag,MFC_CMD_WORD(tid,rid,MFC_PUTQLLUC_CMD))
+
+/* MFC Synchronization Commands */
+#define mfc_sndsig( ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),4,tag,MFC_CMD_WORD(tid,rid,MFC_SNDSIG_CMD))
+#define mfc_sndsigb(ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),4,tag,MFC_CMD_WORD(tid,rid,MFC_SNDSIGB_CMD))
+#define mfc_sndsigf(ls,ea,tag,tid,rid) spu_mfcdma64(ls,mfc_ea2h(ea),mfc_ea2l(ea),4,tag,MFC_CMD_WORD(tid,rid,MFC_SNDSIGF_CMD))
+#define mfc_barrier(tag)       spu_mfcdma32(0,0,0,tag,MFC_BARRIER_CMD)
+#define mfc_eieio(tag,tid,rid) spu_mfcdma32(0,0,0,tag,MFC_CMD_WORD(tid,rid,MFC_EIEIO_CMD))
+#define mfc_sync(tag)          spu_mfcdma32(0,0,0,tag,MFC_SYNC_CMD)
+
+/* DMA Queue */
+#define mfc_stat_cmd_queue()          spu_readchcnt(MFC_Cmd)
+
+/* MFC Tag-Status */
+#define mfc_write_tag_mask(mask)      spu_writech(MFC_WrTagMask,mask)
+#define mfc_read_tag_mask()           spu_readch(MFC_RdTagMask)
+
+#define mfc_write_tag_update(ts)         spu_writech(MFC_WrTagUpdate,ts)
+#define mfc_write_tag_update_immediate() mfc_write_tag_update(MFC_TAG_UPDATE_IMMEDIATE)
+#define mfc_write_tag_update_any()       mfc_write_tag_update(MFC_TAG_UPDATE_ANY)
+#define mfc_write_tag_update_all()       mfc_write_tag_update(MFC_TAG_UPDATE_ALL)
+#define mfc_stat_tag_update()            spu_readchcnt(MFC_WrTagUpdate)
+
+#define mfc_read_tag_status()            spu_readch(MFC_RdTagStat)
+#define mfc_read_tag_status_immediate()  (mfc_write_tag_update_immediate(), mfc_read_tag_status())
+#define mfc_read_tag_status_any()        (mfc_write_tag_update_any(), mfc_read_tag_status())
+#define mfc_read_tag_status_all()        (mfc_write_tag_update_all(), mfc_read_tag_status())
+#define mfc_stat_tag_status()            spu_readchcnt(MFC_RdTagStat)
+
+/* MFC List Stall-and-Notify Tag */
+#define mfc_read_list_stall_status()     spu_readch(MFC_RdListStallStat)
+#define mfc_stat_list_stall_status()     spu_readchcnt(MFC_RdListStallStat)
+#define mfc_write_list_stall_ack(tag)    spu_writech(MFC_WrListStallAck,tag)
+
+/* Atomic DMA */
+#define mfc_read_atomic_status()      spu_readch(MFC_RdAtomicStat)
+#define mfc_stat_atomic_status()      spu_readchcnt(MFC_RdAtomicStat)
+
+/* MFC Multi-source Synchronization */
+#define mfc_write_multi_src_sync_request()   spu_writech(MFC_WrMSSyncReq,0)
+#define mfc_stat_multi_src_sync_request()    spu_readchcnt(MFC_WrMSSyncReq)
+
+/* SPU Signal */
+#define spu_read_signal1()            spu_readch(SPU_RdSigNotify1)
+#define spu_stat_signal1()            spu_readchcnt(SPU_RdSigNotify1)
+#define spu_read_signal2()            spu_readch(SPU_RdSigNotify2)
+#define spu_stat_signal2()            spu_readchcnt(SPU_RdSigNotify2)
+
+/* SPU/PPE Mailbox */
+#define spu_read_in_mbox()            spu_readch(SPU_RdInMbox)
+#define spu_stat_in_mbox()            spu_readchcnt(SPU_RdInMbox)
+#define spu_write_out_mbox(a)         spu_writech(SPU_WrOutMbox,a)
+#define spu_stat_out_mbox()           spu_readchcnt(SPU_WrOutMbox)
+#define spu_write_out_intr_mbox(a)    spu_writech(SPU_WrOutIntrMbox,a)
+#define spu_stat_out_intr_mbox()      spu_readchcnt(SPU_WrOutIntrMbox)
+
+/* SPU Decrementer */
+#define spu_read_decrementer()        spu_readch(SPU_RdDec)
+#define spu_write_decrementer(cnt)    spu_writech(SPU_WrDec,(cnt))
+
+/* SPU Event */
+#define spu_read_event_status()       spu_readch(SPU_RdEventStat)
+#define spu_stat_event_status()       spu_readchcnt(SPU_RdEventStat)
+#define spu_write_event_mask(mask)    spu_writech(SPU_WrEventMask,(mask))
+#define spu_write_event_ack(ack)      spu_writech(SPU_WrEventAck,(ack))
+#define spu_read_event_mask()         spu_readch(SPU_RdEventStatMask)
+
+/* SPU State Management */
+#define spu_read_machine_status()     spu_readch(SPU_MachStat)
+#define spu_write_srr0(srr0)          spu_writech(SPU_WrSRR0,srr0)
+#define spu_read_srr0()               spu_readch(SPU_RdSRR0)
+
+#endif /* __SPU_MFCIO_H__ */
diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf
new file mode 100644 (file)
index 0000000..c05b245
--- /dev/null
@@ -0,0 +1,99 @@
+#  Copyright (C) 2006 Free Software Foundation, Inc.
+#
+#  This file is free software; you can redistribute it and/or modify it under
+#  the terms of the GNU General Public License as published by the Free
+#  Software Foundation; either version 2 of the License, or (at your option) 
+#  any later version.
+#
+#  This file is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this file; see the file COPYING.  If not, write to the Free
+#  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+#  02110-1301, USA.
+
+
+# Suppress building libgcc1.a
+LIBGCC1 =
+CROSS_LIBGCC1 =
+
+# On SPU __word__ is TImode which is too inefficient and incomplete for
+# implementing libgcc routines.
+TARGET_LIBGCC2_CFLAGS = -fPIC -D__word__=SI -mwarn-reloc
+
+LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/spu/float_unssidf.c \
+                        $(srcdir)/config/spu/float_unsdidf.c
+
+LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
+   $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
+
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/spu/t-spu-elf
+       echo '#undef US_SOFTWARE_GOFAST' > dp-bit.c
+       cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c $(srcdir)/config/spu/t-spu-elf
+       echo '#define FLOAT' > fp-bit.c
+       echo '#undef US_SOFTWARE_GOFAST' >> fp-bit.c
+       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# Don't let CTOR_LIST end up in sdata section.
+CRTSTUFF_T_CFLAGS =
+
+#MULTILIB_OPTIONS=mlarge-mem/mtest-abi
+#MULTILIB_DIRNAMES=large-mem test-abi
+#MULTILIB_MATCHES=
+
+# Neither gcc or newlib seem to have a standard way to generate multiple
+# crt*.o files.  So we don't use the standard crt0.o name anymore.
+
+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o crt1.o crtend1.o
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+# Assemble startup files.
+$(T)crti.o: $(srcdir)/config/spu/crti.asm $(GCC_PASSES)
+       $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+       -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/spu/crti.asm
+
+$(T)crtn.o: $(srcdir)/config/spu/crtn.asm $(GCC_PASSES)
+       $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+       -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/spu/crtn.asm
+
+$(T)crt1.o: $(srcdir)/config/spu/crt0.c $(GCC_PASSES)
+       $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+       -O2 \
+       -c -o $(T)crt1.o $(srcdir)/config/spu/crt0.c
+
+$(T)crtend1.o: $(srcdir)/config/spu/crtend.c $(GCC_PASSES)
+       $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+       -O2 \
+       -c -o $(T)crtend1.o $(srcdir)/config/spu/crtend.c
+
+
+spu.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+  $(RTL_H) $(REGS_H) hard-reg-set.h \
+  real.h insn-config.h conditions.h insn-attr.h flags.h $(RECOG_H) \
+  $(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \
+  output.h $(BASIC_BLOCK_H) $(INTEGRATE_H) toplev.h $(GGC_H) $(HASHTAB_H) \
+  $(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h cfglayout.h \
+  $(srcdir)/config/spu/spu-protos.h \
+  $(srcdir)/config/spu/spu-builtins.h \
+  $(srcdir)/config/spu/spu-builtins.def 
+
+spu-c.o: $(srcdir)/config/spu/spu-c.c \
+    $(srcdir)/config/spu/spu-protos.h \
+    $(srcdir)/config/spu/spu-builtins.h \
+    $(srcdir)/config/spu/spu-builtins.def \
+    $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPPLIB_H) \
+    $(TM_P_H) c-pragma.h errors.h coretypes.h $(TM_H) insn-codes.h
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/spu/spu-c.c
+
diff --git a/gcc/config/spu/vec_types.h b/gcc/config/spu/vec_types.h
new file mode 100644 (file)
index 0000000..4d5a2e2
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source files 
+   compiled by GCC, this header file does not by itself cause  the resulting 
+   executable to be covered by the GNU General Public License.  This exception 
+   does not however invalidate any other reasons why the executable file might be 
+   covered by the GNU General Public License.  */ 
+
+#ifndef _VEC_TYPES_H_
+#define _VEC_TYPES_H_  1
+
+#include <spu_intrinsics.h>
+
+/* Define additional PowerPC SIMD/Vector Multi-media eXtension
+ * single keyword vector data types for use in mapping VMX code
+ * to the SPU.
+ */
+#define vec_bchar16    __vector unsigned char
+#define vec_bshort8    __vector unsigned short
+#define vec_pixel8     __vector unsigned short
+#define vec_bint4      __vector unsigned int
+
+#endif /* _VEC_TYPES_H_ */
diff --git a/gcc/config/spu/vmx2spu.h b/gcc/config/spu/vmx2spu.h
new file mode 100644 (file)
index 0000000..7328da4
--- /dev/null
@@ -0,0 +1,3445 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your option) 
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* As a special exception, if you include this header file into source files 
+   compiled by GCC, this header file does not by itself cause  the resulting 
+   executable to be covered by the GNU General Public License.  This exception 
+   does not however invalidate any other reasons why the executable file might be 
+   covered by the GNU General Public License.  */ 
+
+#ifndef _VMX2SPU_H_
+#define _VMX2SPU_H_    1
+
+#ifdef __cplusplus
+
+#ifdef __SPU__
+
+#include <spu_intrinsics.h>
+#include <vec_types.h>
+
+/* This file maps generic VMX intrinsics and predicates to the SPU using 
+ * overloaded C++ functions.
+ */
+
+/************************************************************************
+ *                        INTRINSICS 
+ ************************************************************************/
+
+/* vec_abs (vector absolute value)
+ * =======
+ */
+static inline vec_char16 vec_abs(vec_char16 a)
+{
+  vec_char16 minus_a;
+
+  minus_a = (vec_char16)(spu_add((vec_ushort8)(spu_and(spu_xor(a, 0xFF), 0x7F)), 0x101));
+  return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
+}
+
+static inline vec_short8 vec_abs(vec_short8 a)
+{
+  return (spu_sel(spu_sub(0, a), a, spu_cmpgt(a, -1)));
+}
+
+static inline vec_int4 vec_abs(vec_int4 a)
+{
+  return (spu_sel(spu_sub(0, a), a, spu_cmpgt(a, -1)));
+}
+
+static inline vec_float4 vec_abs(vec_float4 a)
+{
+  return ((vec_float4)(spu_rlmask(spu_sl((vec_uint4)(a), 1), -1)));
+}
+
+/* vec_abss (vector absolute value saturate)
+ * ========
+ */
+static inline vec_char16 vec_abss(vec_char16 a)
+{
+  vec_char16 minus_a;
+
+  minus_a = (vec_char16)spu_add((vec_short8)(spu_xor(a, -1)), 
+                               (vec_short8)(spu_and(spu_cmpgt((vec_uchar16)(a), 0x80), 1)));
+  return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
+}
+
+static inline vec_short8 vec_abss(vec_short8 a)
+{
+  vec_short8 minus_a;
+
+  minus_a = spu_add(spu_sub(0, a), (vec_short8)(spu_cmpeq(a, ((vec_short8){0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000}))));
+  return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
+}
+
+static inline vec_int4 vec_abss(vec_int4 a)
+{
+  vec_int4 minus_a;
+
+  minus_a = spu_add(spu_sub(0, a), (vec_int4)(spu_cmpeq(a, ((vec_int4){0x80000000,0x80000000,0x80000000,0x80000000}))));
+  return (spu_sel(minus_a, a, spu_cmpgt(a, -1)));
+}
+
+
+/* vec_add (vector add)
+ * =======
+ */
+static inline vec_uchar16 vec_add(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((vec_uchar16)(spu_sel(spu_add((vec_ushort8)(a), (vec_ushort8)(b)),
+                               spu_add(spu_and((vec_ushort8)(a), 0xFF00), spu_and((vec_ushort8)(b), 0xFF00)),
+                               spu_splats((unsigned short)(0xFF00)))));
+}
+
+static inline vec_char16 vec_add(vec_char16 a, vec_char16 b)
+{
+  return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b)));
+}
+
+static inline vec_char16 vec_add(vec_bchar16 a, vec_char16 b)
+{
+  return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b)));
+}
+
+static inline vec_char16 vec_add(vec_char16 a, vec_bchar16 b)
+{
+  return ((vec_char16)vec_add((vec_uchar16)(a), (vec_uchar16)(b)));
+}
+
+static inline vec_ushort8 vec_add(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_add(a, b));
+}
+
+static inline vec_short8 vec_add(vec_short8 a, vec_short8 b)
+{
+  return (spu_add(a, b));
+}
+
+static inline vec_short8 vec_add(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_add((vec_short8)(a), b));
+}
+
+static inline vec_short8 vec_add(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_add(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_add(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_add(a, b));
+}
+
+static inline vec_int4 vec_add(vec_int4 a, vec_int4 b)
+{
+  return (spu_add(a, b));
+}
+
+static inline vec_int4 vec_add(vec_bint4 a, vec_int4 b)
+{
+  return (spu_add((vec_int4)(a), b));
+}
+
+static inline vec_int4 vec_add(vec_int4 a, vec_bint4 b)
+{
+  return (spu_add(a, (vec_int4)(b)));
+}
+
+static inline vec_float4 vec_add(vec_float4 a, vec_float4 b)
+{
+  return (spu_add(a, b));
+}
+
+/* vec_addc (vector add carryout unsigned word)
+ * ========
+ */
+#define vec_addc(_a, _b)       spu_genc(_a, _b)
+
+/* vec_adds (vector add saturated)
+ * ========
+ */
+static inline vec_uchar16 vec_adds(vec_uchar16 a, vec_uchar16 b)
+{
+  vec_uchar16 s1, s2, s, d;
+
+  s1 = (vec_uchar16)(spu_add(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8)));
+  s2 = (vec_uchar16)(spu_add(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF)));
+  s  = spu_shuffle(s1, s2, ((vec_uchar16){0, 16,  2, 18,  4, 20,  6, 22,
+                                         8, 24, 10, 26, 12, 28, 14, 30}));
+  d  = spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
+                                         9, 25, 11, 27, 13, 29, 15, 31}));
+  return (spu_or(d, spu_cmpeq(s, 1)));
+}
+
+static inline vec_char16 vec_adds(vec_char16 a, vec_char16 b)
+{
+  vec_uchar16 s1, s2, s, d;
+
+  s1 = (vec_uchar16)(spu_add(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8)));
+  s2 = (vec_uchar16)(spu_add(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF)));
+  s  = spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
+                                         9, 25, 11, 27, 13, 29, 15, 31}));
+  d = spu_sel(s, spu_splats((unsigned char)0x7F), spu_cmpgt(spu_and(s, (vec_uchar16)(spu_nor(a, b))), 0x7F));
+  d = spu_sel(d, spu_splats((unsigned char)0x80), spu_cmpgt(spu_nor(s, (vec_uchar16)(spu_nand(a, b))), 0x7F));
+  return ((vec_char16)(d));
+}
+
+static inline vec_char16 vec_adds(vec_bchar16 a, vec_char16 b)
+{
+  return (vec_adds((vec_char16)(a), b));
+}
+
+static inline vec_char16 vec_adds(vec_char16 a, vec_bchar16 b)
+{
+  return (vec_adds(a, (vec_char16)(b)));
+}
+
+static inline vec_ushort8 vec_adds(vec_ushort8 a, vec_ushort8 b)
+{
+  vec_ushort8 s, d;
+  
+  s = spu_add(a, b);
+  d = spu_or(s, spu_rlmaska(spu_sel(spu_xor(s, -1), a, spu_eqv(a, b)), -15));
+  return (d);
+}
+
+static inline vec_short8 vec_adds(vec_short8 a, vec_short8 b)
+{
+  vec_short8 s, d;
+  
+  s = spu_add(a, b);
+  d = spu_sel(s, spu_splats((signed short)0x7FFF), (vec_ushort8)(spu_rlmaska(spu_and(s, spu_nor(a, b)), -15)));
+  d = spu_sel(d, spu_splats((signed short)0x8000), (vec_ushort8)(spu_rlmaska(spu_nor(s, spu_nand(a, b)), -15)));
+  return (d);
+}
+
+static inline vec_short8 vec_adds(vec_bshort8 a, vec_short8 b)
+{
+  return (vec_adds((vec_short8)(a), b));
+}
+
+static inline vec_short8 vec_adds(vec_short8 a, vec_bshort8 b)
+{
+  return (vec_adds(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_adds(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_or(spu_add(a, b), spu_rlmaska(spu_sl(spu_genc(a, b), 31), -31)));
+}
+
+static inline vec_int4 vec_adds(vec_int4 a, vec_int4 b)
+{
+  vec_int4 s, d;
+  
+  s = spu_add(a, b);
+  d = spu_sel(s, spu_splats((signed int)0x7FFFFFFF), (vec_uint4)spu_rlmaska(spu_and(s, spu_nor(a, b)), -31));
+  d = spu_sel(d, spu_splats((signed int)0x80000000), (vec_uint4)spu_rlmaska(spu_nor(s, spu_nand(a, b)), -31));
+  return (d);
+}
+
+static inline vec_int4 vec_adds(vec_bint4 a, vec_int4 b)
+{
+  return (vec_adds((vec_int4)(a), b));
+}
+
+static inline vec_int4 vec_adds(vec_int4 a, vec_bint4 b)
+{
+  return (vec_adds(a, (vec_int4)(b)));
+}
+
+/* vec_and (vector logical and)
+ * =======
+ */
+static inline vec_uchar16 vec_and(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_and(a, b));
+}
+
+static inline vec_char16 vec_and(vec_char16 a, vec_char16 b)
+{
+  return (spu_and(a, b));
+}
+
+static inline vec_char16 vec_and(vec_bchar16 a, vec_char16 b)
+{
+  return (spu_and((vec_char16)(a), b));
+}
+
+static inline vec_char16 vec_and(vec_char16 a, vec_bchar16 b)
+{
+  return (spu_and(a, (vec_char16)(b)));
+}
+
+static inline vec_ushort8 vec_and(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_and(a, b));
+}
+
+static inline vec_short8 vec_and(vec_short8 a, vec_short8 b)
+{
+  return (spu_and(a, b));
+}
+
+static inline vec_short8 vec_and(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_and((vec_short8)(a), b));
+}
+
+static inline vec_short8 vec_and(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_and(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_and(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_and(a, b));
+}
+
+static inline vec_int4 vec_and(vec_int4 a, vec_int4 b)
+{
+  return (spu_and(a, b));
+}
+
+static inline vec_int4 vec_and(vec_bint4 a, vec_int4 b)
+{
+  return (spu_and((vec_int4)(a), b));
+}
+
+static inline vec_int4 vec_and(vec_int4 a, vec_bint4 b)
+{
+  return (spu_and(a, (vec_int4)(b)));
+}
+
+static inline vec_float4 vec_and(vec_float4 a, vec_float4 b)
+{
+  return (spu_and(a, b));
+}
+
+static inline vec_float4 vec_and(vec_bint4 a, vec_float4 b)
+{
+  return (spu_and((vec_float4)(a),b));
+}
+
+static inline vec_float4 vec_and(vec_float4 a, vec_bint4 b)
+{
+  return (spu_and(a, (vec_float4)(b)));
+}
+
+
+/* vec_andc (vector logical and with complement) 
+ * ========
+ */
+static inline vec_uchar16 vec_andc(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_andc(a, b));
+}
+
+static inline vec_char16 vec_andc(vec_char16 a, vec_char16 b)
+{
+  return (spu_andc(a, b));
+}
+
+static inline vec_char16 vec_andc(vec_bchar16 a, vec_char16 b)
+{
+  return (spu_andc((vec_char16)(a), b));
+}
+
+static inline vec_char16 vec_andc(vec_char16 a, vec_bchar16 b)
+{
+  return (spu_andc(a, (vec_char16)(b)));
+}
+
+static inline vec_ushort8 vec_andc(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_andc(a, b));
+}
+
+static inline vec_short8 vec_andc(vec_short8 a, vec_short8 b)
+{
+  return (spu_andc(a, b));
+}
+
+static inline vec_short8 vec_andc(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_andc((vec_short8)(a), b));
+}
+
+static inline vec_short8 vec_andc(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_andc(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_andc(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_andc(a, b));
+}
+
+static inline vec_int4 vec_andc(vec_int4 a, vec_int4 b)
+{
+  return (spu_andc(a, b));
+}
+
+static inline vec_int4 vec_andc(vec_bint4 a, vec_int4 b)
+{
+  return (spu_andc((vec_int4)(a), b));
+}
+
+static inline vec_int4 vec_andc(vec_int4 a, vec_bint4 b)
+{
+  return (spu_andc(a, (vec_int4)(b)));
+}
+
+static inline vec_float4 vec_andc(vec_float4 a, vec_float4 b)
+{
+  return (spu_andc(a,b));
+}
+
+static inline vec_float4 vec_andc(vec_bint4 a, vec_float4 b)
+{
+  return (spu_andc((vec_float4)(a),b));
+}
+
+static inline vec_float4 vec_andc(vec_float4 a, vec_bint4 b)
+{
+  return (spu_andc(a, (vec_float4)(b)));
+}
+
+/* vec_avg (vector average)
+ * =======
+ */
+static inline vec_uchar16 vec_avg(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_avg(a, b));
+}
+
+static inline vec_char16 vec_avg(vec_char16 a, vec_char16 b)
+{
+  return ((vec_char16)(spu_xor(spu_avg((vec_uchar16)(a), (vec_uchar16)(b)), 
+                              (vec_uchar16)(spu_and(spu_xor(a,b), 0x80)))));
+}
+
+static inline vec_ushort8 vec_avg(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_add(spu_add(spu_rlmask(a, -1), spu_rlmask(b, -1)), 
+                 spu_and(spu_or(a, b), 1)));
+}
+
+static inline vec_short8 vec_avg(vec_short8 a, vec_short8 b)
+{
+  return (spu_add(spu_add(spu_rlmaska(a, -1), spu_rlmaska(b, -1)), 
+                 spu_and(spu_or(a, b), 1)));
+}
+
+static inline vec_uint4 vec_avg(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_add(spu_add(spu_rlmask(a, -1), spu_rlmask(b, -1)), 
+                 spu_and(spu_or(a, b), 1)));
+}
+
+static inline vec_int4 vec_avg(vec_int4 a, vec_int4 b)
+{
+  return (spu_add(spu_add(spu_rlmaska(a, -1), spu_rlmaska(b, -1)), 
+                 spu_and(spu_or(a, b), 1)));
+}
+
+
+/* vec_ceil (vector ceiling)
+ * ========
+ */
+static inline vec_float4 vec_ceil(vec_float4 a)
+{
+  vec_int4  exp;
+  vec_uint4 mask;
+
+  a = spu_add(a, (vec_float4)(spu_and(spu_xor(spu_rlmaska((vec_int4)a, -31), -1), spu_splats((signed int)0x3F7FFFFF))));
+  exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
+  mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
+  mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
+  mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
+
+  return ((vec_float4)(spu_andc((vec_uint4)(a), mask)));
+}
+
+
+/* vec_cmpb (vector compare bounds floating-point)
+ * ========
+ */
+static inline vec_int4 vec_cmpb(vec_float4 a, vec_float4 b)
+{
+  vec_int4 b0 = (vec_int4)spu_splats(0x80000000);
+  vec_int4 b1 = (vec_int4)spu_splats(0x40000000);
+
+  return (spu_or(spu_and((vec_int4)spu_cmpgt(a, b), b0), 
+                spu_and((vec_int4)spu_cmpgt(spu_xor(b, (vec_float4)(b0)), a), b1)));
+}
+
+/* vec_cmpeq (vector compare equal)
+ * =========
+ */
+#define vec_cmpeq(_a, _b)      spu_cmpeq(_a, _b)
+
+
+/* vec_cmpge (vector compare greater than or equal)
+ * =========
+ */
+static inline vec_bint4 vec_cmpge(vec_float4 a, vec_float4 b)
+{
+  return (spu_xor(spu_cmpgt(b, a), -1));
+}
+
+
+/* vec_cmpgt (vector compare greater than)
+ * =========
+ */
+#define vec_cmpgt(_a, _b)      spu_cmpgt(_a, _b)
+
+
+/* vec_cmple (vector compare less than or equal)
+ * =========
+ */
+static inline vec_bint4 vec_cmple(vec_float4 a, vec_float4 b)
+{
+  return (spu_xor(spu_cmpgt(a, b), -1));
+}
+
+
+/* vec_cmplt (vector compare less than)
+ * =========
+ */
+#define vec_cmplt(_a, _b)      spu_cmpgt(_b, _a)
+
+
+/* vec_ctf (vector convert from fixed-point word)
+ * =======
+ */
+#define vec_ctf(_a, _b)                spu_convtf(_a, _b)
+
+
+/* vec_cts (vector convert to signed fixed-point word saturate)
+ * =======
+ */
+#define vec_cts(_a, _b)                spu_convts(_a, _b)
+
+
+/* vec_ctu (vector convert to unsigned fixed-point word saturate)
+ * =======
+ */
+#define vec_ctu(_a, _b)                spu_convtu(_a, _b)
+
+
+/* vec_dss (vector data stream stop)
+ * =======
+ */
+#define vec_dss(_a)
+
+
+/* vec_dssall (vector data stream stop all)
+ * ==========
+ */
+#define vec_dssall()
+
+
+/* vec_dst (vector data stream touch)
+ * =======
+ */
+#define vec_dst(_a, _b, _c)
+
+
+/* vec_dstst (vector data stream touch for store)
+ * =========
+ */
+#define vec_dstst(_a, _b, _c)
+
+
+/* vec_dststt (vector data stream touch for store transient)
+ * ==========
+ */
+#define vec_dststt(_a, _b, _c)
+
+
+/* vec_dstt (vector data stream touch transient)
+ * ========
+ */
+#define vec_dstt(_a, _b, _c)
+
+
+/* vec_expte (vector is 2 raised tp the exponent estimate floating-point)
+ * =========
+ */
+static inline vec_float4 vec_expte(vec_float4 a)
+{
+  vec_float4 bias, frac, exp;
+  vec_int4 ia;
+
+  bias = (vec_float4)(spu_andc(spu_splats((signed int)0x3F7FFFFF), spu_rlmaska((vec_int4)(a), -31)));
+  ia   = spu_convts(spu_add(a, bias), 0);
+  frac = spu_sub(spu_convtf(ia, 0), a);
+  exp  = (vec_float4)(spu_sl(spu_add(ia, 127), 23));
+
+  return (spu_mul(spu_madd(spu_madd(spu_splats(0.17157287f), frac, spu_splats(-0.67157287f)),
+                          frac, spu_splats(1.0f)), exp));
+}
+
+
+/* vec_floor (vector floor)
+ * =========
+ */
+static inline vec_float4 vec_floor(vec_float4 a)
+{
+  vec_int4  exp;
+  vec_uint4 mask;
+
+  a = spu_sub(a, (vec_float4)(spu_and(spu_rlmaska((vec_int4)a, -31), spu_splats((signed int)0x3F7FFFFF))));
+  exp = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
+  mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
+  mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
+  mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
+
+  return ((vec_float4)(spu_andc((vec_uint4)(a), mask)));
+}
+
+
+/* vec_ld (vector load indexed)
+ * ======
+ */
+static inline vec_uchar16 vec_ld(int a, unsigned char *b)
+{
+  return (*((vec_uchar16 *)(b+a)));
+}
+
+static inline vec_uchar16 vec_ld(int a, vec_uchar16 *b)
+{
+  return (*((vec_uchar16 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_char16 vec_ld(int a, signed char *b)
+{
+  return (*((vec_char16 *)(b+a)));
+}
+
+static inline vec_char16 vec_ld(int a, vec_char16 *b)
+{
+  return (*((vec_char16 *)((signed char *)(b)+a)));
+}
+
+static inline vec_ushort8 vec_ld(int a, unsigned short *b)
+{
+  return (*((vec_ushort8 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_ushort8 vec_ld(int a, vec_ushort8 *b)
+{
+  return (*((vec_ushort8 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_short8 vec_ld(int a, signed short *b)
+{
+  return (*((vec_short8 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_short8 vec_ld(int a, vec_short8 *b)
+{
+  return (*((vec_short8 *)((signed char *)(b)+a)));
+}
+
+static inline vec_uint4 vec_ld(int a, unsigned int *b)
+{
+  return (*((vec_uint4 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_uint4 vec_ld(int a, vec_uint4 *b)
+{
+  return (*((vec_uint4 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_int4 vec_ld(int a, signed int *b)
+{
+  return (*((vec_int4 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_int4 vec_ld(int a, vec_int4 *b)
+{
+  return (*((vec_int4 *)((signed char *)(b)+a)));
+}
+
+static inline vec_float4 vec_ld(int a, float *b)
+{
+  return (*((vec_float4 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_float4 vec_ld(int a, vec_float4 *b)
+{
+  return (*((vec_float4 *)((unsigned char *)(b)+a)));
+}
+
+/* vec_lde (vector load element indexed)
+ * =======
+ */
+static inline vec_uchar16 vec_lde(int a, unsigned char *b)
+{
+  return (*((vec_uchar16 *)(b+a)));
+}
+
+static inline vec_char16 vec_lde(int a, signed char *b)
+{
+  return (*((vec_char16 *)(b+a)));
+}
+
+static inline vec_ushort8 vec_lde(int a, unsigned short *b)
+{
+  return (*((vec_ushort8 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_short8 vec_lde(int a, signed short *b)
+{
+  return (*((vec_short8 *)((unsigned char *)(b)+a)));
+}
+
+
+static inline vec_uint4 vec_lde(int a, unsigned int *b)
+{
+  return (*((vec_uint4 *)((unsigned char *)(b)+a)));
+}
+
+static inline vec_int4 vec_lde(int a, signed int *b)
+{
+  return (*((vec_int4 *)((unsigned char *)(b)+a)));
+}
+
+
+static inline vec_float4 vec_lde(int a, float *b)
+{
+  return (*((vec_float4 *)((unsigned char *)(b)+a)));
+}
+
+/* vec_ldl (vector load indexed LRU)
+ * =======
+ */
+#define vec_ldl(_a, _b)                vec_ld(_a, _b)
+
+
+/* vec_loge (vector log2 estimate floating-point)
+ * ========
+ */
+static inline vec_float4 vec_loge(vec_float4 a)
+{
+  vec_int4 exp;
+  vec_float4 frac;
+
+  exp  = spu_add((vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)), -127);
+  frac = (vec_float4)(spu_sub((vec_int4)(a), spu_sl(exp, 23)));
+
+  return (spu_madd(spu_madd(spu_splats(-0.33985f), frac, spu_splats(2.01955f)), 
+                  frac, spu_sub(spu_convtf(exp, 0), spu_splats(1.6797f))));
+}
+
+
+/* vec_lvsl (vector load for shift left)
+ * ========
+ */
+static inline vec_uchar16 vec_lvsl(int a, unsigned char *b)
+{
+  return ((vec_uchar16)spu_add((vec_ushort8)(spu_splats((unsigned char)((a + (int)(b)) & 0xF))), 
+                              ((vec_ushort8){0x0001, 0x0203, 0x0405, 0x0607,
+                                             0x0809, 0x0A0B, 0x0C0D, 0x0E0F})));
+}
+
+static inline vec_uchar16 vec_lvsl(int a, signed char *b)
+{
+  return (vec_lvsl(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsl(int a, unsigned short *b)
+{
+  return (vec_lvsl(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsl(int a, short *b)
+{
+  return (vec_lvsl(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsl(int a, unsigned int *b)
+{
+  return (vec_lvsl(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsl(int a, int *b)
+{
+  return (vec_lvsl(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsl(int a, float *b)
+{
+  return (vec_lvsl(a, (unsigned char *)b));
+}
+
+
+/* vec_lvsr (vector load for shift right)
+ * ========
+ */
+static  inline vec_uchar16 vec_lvsr(int a, unsigned char *b)
+{
+  return ((vec_uchar16)(spu_sub(((vec_ushort8){0x1011, 0x1213, 0x1415, 0x1617,
+                                              0x1819, 0x1A1B, 0x1C1D, 0x1E1F}),
+                               (vec_ushort8)(spu_splats((unsigned char)((a + (int)(b)) & 0xF))))));
+}
+
+static inline vec_uchar16 vec_lvsr(int a, signed char *b)
+{
+  return (vec_lvsr(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsr(int a, unsigned short *b)
+{
+  return (vec_lvsr(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsr(int a, short *b)
+{
+  return (vec_lvsr(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsr(int a, unsigned int *b)
+{
+  return (vec_lvsr(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsr(int a, int *b)
+{
+  return (vec_lvsr(a, (unsigned char *)b));
+}
+
+static inline vec_uchar16 vec_lvsr(int a, float *b)
+{
+  return (vec_lvsr(a, (unsigned char *)b));
+}
+
+/* vec_madd (vector multiply add)
+ * ========
+ */
+#define vec_madd(_a, _b, _c)   spu_madd(_a, _b, _c)
+
+
+
+/* vec_madds (vector multiply add saturate)
+ * =========
+ */
+static inline vec_short8 vec_madds(vec_short8 a, vec_short8 b, vec_short8 c)
+{
+  return (vec_adds(c, spu_sel((vec_short8)(spu_sl(spu_mule(a, b), 1)),
+                             (vec_short8)(spu_rlmask(spu_mulo(a, b), -15)),
+                             ((vec_ushort8){0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF}))));
+}
+
+/* vec_max (vector maximum)
+ * =======
+ */
+static inline vec_uchar16 vec_max(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_sel(b, a, spu_cmpgt(a, b)));
+}
+
+static inline vec_char16 vec_max(vec_char16 a, vec_char16 b)
+{
+  return (spu_sel(b, a, spu_cmpgt(a, b)));
+}
+
+static inline vec_char16 vec_max(vec_bchar16 a, vec_char16 b)
+{
+  return (spu_sel(b, (vec_char16)(a), spu_cmpgt((vec_char16)(a), b)));
+}
+
+static inline vec_char16 vec_max(vec_char16 a, vec_bchar16 b)
+{
+  return (spu_sel((vec_char16)(b), a, spu_cmpgt(a, (vec_char16)(b))));
+}
+
+static inline vec_ushort8 vec_max(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_sel(b, a, spu_cmpgt(a, b)));
+}
+
+static inline vec_short8 vec_max(vec_short8 a, vec_short8 b)
+{
+  return (spu_sel(b, a, spu_cmpgt(a, b)));
+}
+
+static inline vec_short8 vec_max(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_sel(b, (vec_short8)(a), spu_cmpgt((vec_short8)(a), b)));
+}
+
+static inline vec_short8 vec_max(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_sel((vec_short8)(b), a, spu_cmpgt(a, (vec_short8)(b))));
+}
+
+static inline vec_uint4 vec_max(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_sel(b, a, spu_cmpgt(a, b)));
+}
+
+static inline vec_int4 vec_max(vec_int4 a, vec_int4 b)
+{
+  return (spu_sel(b, a, spu_cmpgt(a, b)));
+}
+
+static inline vec_int4 vec_max(vec_bint4 a, vec_int4 b)
+{
+  return (spu_sel(b, (vec_int4)(a), spu_cmpgt((vec_int4)(a), b)));
+}
+
+static inline vec_int4 vec_max(vec_int4 a, vec_bint4 b)
+{
+  return (spu_sel((vec_int4)(b), a, spu_cmpgt(a, (vec_int4)(b))));
+}
+
+static inline vec_float4 vec_max(vec_float4 a, vec_float4 b)
+{
+  return (spu_sel(b, a, spu_cmpgt(a, b)));
+}
+
+
+/* vec_mergeh (vector merge high)
+ * ==========
+ */
+static inline vec_uchar16 vec_mergeh(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){0, 16, 1, 17, 2, 18, 3, 19,
+                                          4, 20, 5, 21, 6, 22, 7, 23})));
+}
+
+static inline vec_char16 vec_mergeh(vec_char16 a, vec_char16 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){0, 16, 1, 17, 2, 18, 3, 19,
+                                          4, 20, 5, 21, 6, 22, 7, 23})));
+}
+
+static inline vec_ushort8 vec_mergeh(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 16, 17, 2, 3, 18, 19, 
+                                          4, 5, 20, 21, 6, 7, 22, 23})));
+}
+
+static inline vec_short8 vec_mergeh(vec_short8 a, vec_short8 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 16, 17, 2, 3, 18, 19, 
+                                          4, 5, 20, 21, 6, 7, 22, 23})));
+}
+
+static inline vec_uint4 vec_mergeh(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, 
+                                          4, 5, 6, 7, 20, 21, 22, 23})));
+}
+
+static inline vec_int4 vec_mergeh(vec_int4 a, vec_int4 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, 
+                                          4, 5, 6, 7, 20, 21, 22, 23})));
+}
+
+static inline vec_float4 vec_mergeh(vec_float4 a, vec_float4 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){0, 1, 2, 3, 16, 17, 18, 19, 
+                                          4, 5, 6, 7, 20, 21, 22, 23})));
+}
+
+/* vec_mergel (vector merge low)
+ * ==========
+ */
+static inline vec_uchar16 vec_mergel(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){ 8, 24,  9, 25, 10, 26, 11, 27, 
+                                          12, 28, 13, 29, 14, 30, 15, 31})));
+}
+
+static inline vec_char16 vec_mergel(vec_char16 a, vec_char16 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){ 8, 24,  9, 25, 10, 26, 11, 27, 
+                                          12, 28, 13, 29, 14, 30, 15, 31})));
+}
+
+static inline vec_ushort8 vec_mergel(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 24, 25, 10, 11, 26, 27, 
+                                          12, 13, 28, 29, 14, 15, 30, 31})));
+}
+
+static inline vec_short8 vec_mergel(vec_short8 a, vec_short8 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 24, 25, 10, 11, 26, 27, 
+                                          12, 13, 28, 29, 14, 15, 30, 31})));
+}
+
+static inline vec_uint4 vec_mergel(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 10, 11, 24, 25, 26, 27, 
+                                          12, 13, 14, 15, 28, 29, 30, 31})));
+}
+
+static inline vec_int4 vec_mergel(vec_int4 a, vec_int4 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 10, 11, 24, 25, 26, 27, 
+                                          12, 13, 14, 15, 28, 29, 30, 31})));
+}
+
+static inline vec_float4 vec_mergel(vec_float4 a, vec_float4 b)
+{
+  return (spu_shuffle(a, b, ((vec_uchar16){ 8,  9, 10, 11, 24, 25, 26, 27, 
+                                          12, 13, 14, 15, 28, 29, 30, 31})));
+}
+
+/* vec_mfvscr (vector move from vector status and control register)
+ * ==========
+ */
+static inline vec_ushort8 vec_mfvscr()
+{
+  return ((vec_ushort8)spu_splats(0));                 /* not supported */
+}
+
+
+/* vec_min (vector minimum)
+ * =======
+ */
+static inline vec_uchar16 vec_min(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_sel(a, b, spu_cmpgt(a, b)));
+}
+
+static inline vec_char16 vec_min(vec_char16 a, vec_char16 b)
+{
+  return (spu_sel(a, b, spu_cmpgt(a, b)));
+}
+
+static inline vec_char16 vec_min(vec_bchar16 a, vec_char16 b)
+{
+  return (spu_sel((vec_char16)(a), b, spu_cmpgt((vec_char16)(a), b)));
+}
+
+static inline vec_char16 vec_min(vec_char16 a, vec_bchar16 b)
+{
+  return (spu_sel(a, (vec_char16)(b), spu_cmpgt(a, (vec_char16)(b))));
+}
+
+static inline vec_ushort8 vec_min(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_sel(a, b, spu_cmpgt(a, b)));
+}
+
+static inline vec_short8 vec_min(vec_short8 a, vec_short8 b)
+{
+  return (spu_sel(a, b, spu_cmpgt(a, b)));
+}
+
+static inline vec_short8 vec_min(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_sel((vec_short8)(a), b, spu_cmpgt((vec_short8)(a), b)));
+}
+
+static inline vec_short8 vec_min(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_sel(a, (vec_short8)(b), spu_cmpgt(a, (vec_short8)(b))));
+}
+
+static inline vec_uint4 vec_min(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_sel(a, b, spu_cmpgt(a, b)));
+}
+
+static inline vec_int4 vec_min(vec_int4 a, vec_int4 b)
+{
+  return (spu_sel(a, b, spu_cmpgt(a, b)));
+}
+
+static inline vec_int4 vec_min(vec_bint4 a, vec_int4 b)
+{
+  return (spu_sel((vec_int4)(a), b, spu_cmpgt((vec_int4)(a), b)));
+}
+
+static inline vec_int4 vec_min(vec_int4 a, vec_bint4 b)
+{
+  return (spu_sel(a, (vec_int4)(b), spu_cmpgt(a, (vec_int4)(b))));
+}
+
+static inline vec_float4 vec_min(vec_float4 a, vec_float4 b)
+{
+  return (spu_sel(a, b, spu_cmpgt(a, b)));
+}
+
+/* vec_mladd (vector multiply low and add unsigned half word)
+ * =========
+ */
+static inline vec_short8 vec_mladd(vec_short8 a, vec_short8 b, vec_short8 c)
+{
+  return ((vec_short8)(spu_shuffle(spu_madd((vec_short8)(spu_rl((vec_uint4)(a), -16)),
+                                           (vec_short8)(spu_rl((vec_uint4)(b), -16)),
+                                           (vec_int4)(spu_rl((vec_uint4)(c), -16))),
+                                  spu_madd(a, b, spu_extend(c)),
+                                  ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
+                                                 10, 11, 26, 27, 14, 15, 30, 31}))));
+}
+
+
+static inline vec_ushort8 vec_mladd(vec_ushort8 a, vec_ushort8 b, vec_ushort8 c)
+{
+  return ((vec_ushort8)(vec_mladd((vec_short8)(a), (vec_short8)(b), (vec_short8)(c))));
+}
+
+static inline vec_short8 vec_mladd(vec_ushort8 a, vec_short8 b, vec_short8 c)
+{
+  return (vec_mladd((vec_short8)(a), b, c));
+}
+
+static inline vec_short8 vec_mladd(vec_short8 a, vec_ushort8 b, vec_ushort8 c)
+{
+  return (vec_mladd(a, (vec_short8)(b), (vec_short8)(c)));
+}
+
+
+/* vec_mradds (vector multiply round and add saturate)
+ * ==========
+ */
+static inline vec_short8 vec_mradds(vec_short8 a, vec_short8 b, vec_short8 c)
+{
+  vec_int4 round = (vec_int4)spu_splats(0x4000);
+  vec_short8 hi, lo;
+
+  hi = (vec_short8)(spu_sl(spu_add(spu_mule(a, b), round), 1));
+  lo = (vec_short8)(spu_rlmask(spu_add(spu_mulo(a, b), round), -15));
+
+  return (vec_adds(spu_sel(hi, lo, ((vec_ushort8){0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF, 0, 0xFFFF})), c));
+}
+
+
+/* vec_msum (vector multiply sum)
+ * ========
+ */
+static inline vec_uint4 vec_msum(vec_uchar16 a, vec_uchar16 b, vec_uint4 c)
+{
+  vec_ushort8 a1, a2, b1, b2;
+  vec_uint4 p1, p2;
+
+  a1 = spu_and((vec_ushort8)(a), 0xFF);
+  a2 = spu_rlmask((vec_ushort8)(a), -8);
+  b1 = spu_and((vec_ushort8)(b), 0xFF);
+  b2 = spu_rlmask((vec_ushort8)(b), -8);
+
+  p1 = spu_add(spu_mulo(a1, b1), spu_mulo(spu_rlqwbyte(a1, -2), spu_rlqwbyte(b1, -2)));
+  p2 = spu_add(spu_mulo(a2, b2), spu_mulo(spu_rlqwbyte(a2, -2), spu_rlqwbyte(b2, -2)));
+  return (spu_add(p2, spu_add(p1, c)));
+}
+
+static inline vec_int4 vec_msum(vec_char16 a, vec_uchar16 b, vec_int4 c)
+{
+  vec_short8 a1, a2, b1, b2;
+  vec_int4 p1, p2;
+
+  a1 = (vec_short8)(spu_extend(a));
+  a2 = spu_rlmaska((vec_short8)(a), -8);
+  b1 = (vec_short8)(spu_and((vec_ushort8)(b), 0xFF));
+  b2 = (vec_short8)spu_rlmask((vec_ushort8)(b), -8);
+
+  p1 = spu_add(spu_mulo(a1, b1), spu_mulo(spu_rlqwbyte(a1, -2), spu_rlqwbyte(b1, -2)));
+  p2 = spu_add(spu_mulo(a2, b2), spu_mulo(spu_rlqwbyte(a2, -2), spu_rlqwbyte(b2, -2)));
+  return (spu_add(p2, spu_add(p1, c)));
+}
+
+static inline vec_uint4 vec_msum(vec_ushort8 a, vec_ushort8 b, vec_uint4 c)
+{
+  return (spu_add(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c));
+}
+
+static inline vec_int4 vec_msum(vec_short8 a, vec_short8 b, vec_int4 c)
+{
+  return (spu_add(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c));
+}
+
+
+/* vec_msums (vector multiply sum saturate)
+ * ========
+ */
+static inline vec_uint4 vec_msums(vec_ushort8 a, vec_ushort8 b, vec_uint4 c)
+{
+  vec_uint4 p1, p2;
+
+  p1 = spu_mulo(a, b);
+  p2 = spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2));
+
+  return (vec_adds(p2, vec_adds(p1, c)));
+}
+
+static inline vec_int4 vec_msums(vec_short8 a, vec_short8 b, vec_int4 c)
+{
+  return (vec_adds(spu_add(spu_mulo(a, b), spu_mulo(spu_rlqwbyte(a, -2), spu_rlqwbyte(b, -2))), c));
+}
+
+/* vec_mtvscr (vector move to vector status and control register)
+ * ==========
+ */
+#define vec_mtvscr(_a)         /* not supported */
+
+
+/* vec_mule (vector multiply even)
+ * ========
+ */
+static inline vec_ushort8 vec_mule(vec_uchar16 a, vec_uchar16 b)
+{
+  vec_ushort8 hi, lo;
+
+  hi = (vec_ushort8)spu_mulo((vec_ushort8)(spu_rlmask((vec_uint4)(a), -24)), 
+                            (vec_ushort8)(spu_rlmask((vec_uint4)(b), -24)));
+  lo = (vec_ushort8)spu_mulo((vec_ushort8)(spu_rlmask((vec_short8)(a), -8)), 
+                            (vec_ushort8)(spu_rlmask((vec_short8)(b), -8)));
+
+  return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
+                                            10, 11, 26, 27, 14, 15, 30, 31})));
+}
+
+static inline vec_short8 vec_mule(vec_char16 a, vec_char16 b)
+{
+  vec_short8 hi, lo;
+
+  hi = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_uint4)(a), -24)), 
+                           (vec_short8)(spu_rlmaska((vec_uint4)(b), -24)));
+  lo = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_short8)(a), -8)), 
+                           (vec_short8)(spu_rlmaska((vec_short8)(b), -8)));
+
+  return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
+                                            10, 11, 26, 27, 14, 15, 30, 31})));
+}
+
+static inline vec_uint4 vec_mule(vec_ushort8 a, vec_ushort8 b)
+{
+ return (spu_mulo((vec_ushort8)spu_rlmask((vec_uint4)(a), -16),
+                 (vec_ushort8)spu_rlmask((vec_uint4)(b), -16)));
+}
+
+
+static inline vec_int4 vec_mule(vec_short8 a, vec_short8 b)
+{
+ return (spu_mulo((vec_short8)spu_rlmaska((vec_int4)(a), -16),
+                 (vec_short8)spu_rlmaska((vec_int4)(b), -16)));
+}
+
+
+/* vec_mulo (vector multiply odd)
+ * ========
+ */
+static inline vec_ushort8 vec_mulo(vec_uchar16 a, vec_uchar16 b)
+{
+  vec_ushort8 hi, lo;
+
+  hi = (vec_ushort8)spu_mulo((vec_ushort8)(spu_and(spu_rlmask((vec_uint4)(a), -16), 0xFF)), 
+                            (vec_ushort8)(spu_and(spu_rlmask((vec_uint4)(b), -16), 0xFF)));
+  lo = (vec_ushort8)spu_mulo(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF));
+
+  return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
+                                            10, 11, 26, 27, 14, 15, 30, 31})));
+}
+
+static inline vec_short8 vec_mulo(vec_char16 a, vec_char16 b)
+{
+  vec_short8 aa, bb, hi, lo;
+
+  aa = spu_extend(a);
+  bb = spu_extend(b);
+
+  hi = (vec_short8)spu_mulo((vec_short8)(spu_rlmaska((vec_uint4)(aa), -16)), 
+               (vec_short8)(spu_rlmaska((vec_uint4)(bb), -16)));
+  lo = (vec_short8)spu_mulo(aa, bb);
+  return (spu_shuffle(hi, lo, ((vec_uchar16){ 2,  3, 18, 19,  6,  7, 22, 23,
+                                            10, 11, 26, 27, 14, 15, 30, 31})));
+}
+
+static inline vec_uint4 vec_mulo(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_mulo(a, b));
+}
+
+
+static inline vec_int4 vec_mulo(vec_short8 a, vec_short8 b)
+{
+  return (spu_mulo(a, b));
+}
+
+
+/* vec_nmsub (vector negative multiply subtract)
+ * =========
+ */
+#define vec_nmsub(_a, _b, _c)  spu_nmsub(_a, _b, _c)
+
+
+/* vec_nor (vector logical nor)
+ * =======
+ */
+#define vec_nor(_a, _b)                spu_nor(_a, _b)
+
+
+/* vec_or (vector logical or)
+ * ======
+ */
+static inline vec_uchar16 vec_or(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_or(a, b));
+}
+
+static inline vec_char16 vec_or(vec_char16 a, vec_char16 b)
+{
+  return (spu_or(a, b));
+}
+
+static inline vec_char16 vec_or(vec_bchar16 a, vec_char16 b)
+{
+  return (spu_or((vec_char16)(a), b));
+}
+
+static inline vec_char16 vec_or(vec_char16 a, vec_bchar16 b)
+{
+  return (spu_or(a, (vec_char16)(b)));
+}
+
+static inline vec_ushort8 vec_or(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_or(a, b));
+}
+
+static inline vec_short8 vec_or(vec_short8 a, vec_short8 b)
+{
+  return (spu_or(a, b));
+}
+
+static inline vec_short8 vec_or(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_or((vec_short8)(a), b));
+}
+
+static inline vec_short8 vec_or(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_or(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_or(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_or(a, b));
+}
+
+static inline vec_int4 vec_or(vec_int4 a, vec_int4 b)
+{
+  return (spu_or(a, b));
+}
+
+static inline vec_int4 vec_or(vec_bint4 a, vec_int4 b)
+{
+  return (spu_or((vec_int4)(a), b));
+}
+
+static inline vec_int4 vec_or(vec_int4 a, vec_bint4 b)
+{
+  return (spu_or(a, (vec_int4)(b)));
+}
+
+static inline vec_float4 vec_or(vec_float4 a, vec_float4 b)
+{
+  return (spu_or(a, b));
+}
+
+static inline vec_float4 vec_or(vec_bint4 a, vec_float4 b)
+{
+  return (spu_or((vec_float4)(a),b));
+}
+
+static inline vec_float4 vec_or(vec_float4 a, vec_bint4 b)
+{
+  return (spu_or(a, (vec_float4)(b)));
+}
+
+
+/* vec_pack (vector pack)
+ * ========
+ */
+static inline vec_uchar16 vec_pack(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((vec_uchar16)spu_shuffle(a, b, ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
+                                                       17, 19, 21, 23, 25, 27, 29, 31})));
+}
+
+static inline vec_char16 vec_pack(vec_short8 a, vec_short8 b)
+{
+  return ((vec_char16)spu_shuffle(a, b, ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
+                                                      17, 19, 21, 23, 25, 27, 29, 31})));
+}
+
+static inline vec_ushort8 vec_pack(vec_uint4 a, vec_uint4 b)
+{
+  return ((vec_ushort8)spu_shuffle(a, b, ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
+                                                       18, 19, 22, 23, 26, 27, 30, 31})));
+}
+
+static inline vec_short8 vec_pack(vec_int4 a, vec_int4 b)
+{
+  return ((vec_short8)spu_shuffle(a, b, ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
+                                                      18, 19, 22, 23, 26, 27, 30, 31})));
+}
+
+
+/* vec_packpx (vector pack pixel)
+ * ==========
+ */
+static inline vec_pixel8 vec_packpx(vec_uint4 a, vec_uint4 b)
+{
+  vec_uint4 x03FF = (vec_uint4)(spu_splats((unsigned short)0x03FF));
+  vec_uint4 x001F = (vec_uint4)(spu_splats((unsigned short)0x001F));
+
+  return ((vec_pixel8)(spu_shuffle(spu_sel(spu_sel(spu_sl(a, 7), spu_sl(a, 10), x03FF),
+                                          spu_sl(a, 13), x001F),
+                                  spu_sel(spu_sel(spu_sl(b, 7), spu_sl(b, 10), x03FF),
+                                          spu_sl(b, 13), x001F),
+                                  ((vec_uchar16){ 0,  1,  4,  5,   8,  9, 12, 13,
+                                                 16, 17, 20, 21, 24, 25, 28, 29}))));
+}
+
+
+/* vec_packs (vector pack saturate)
+ * =========
+ */
+static inline vec_uchar16 vec_packs(vec_ushort8 a, vec_ushort8 b)
+{
+  vec_ushort8 max = spu_splats((unsigned short)0x00FF);
+  
+  return ((vec_uchar16)(spu_shuffle(spu_sel(a, max, spu_cmpgt(a, 255)),
+                                   spu_sel(b, max, spu_cmpgt(b, 255)),
+                                   ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
+                                                  17, 19, 21, 23, 25, 27, 29, 31}))));
+}
+
+static inline vec_char16 vec_packs(vec_short8 a, vec_short8 b)
+{
+  vec_short8 max = spu_splats((signed short)0x007F);
+  vec_short8 min = spu_splats((signed short)0xFF80);
+  
+  return ((vec_char16)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, 127)), spu_cmpgt(a, -128)),
+                                   spu_sel(min, spu_sel(b, max, spu_cmpgt(b, 127)), spu_cmpgt(b, -128)),
+                                  ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
+                                                 17, 19, 21, 23, 25, 27, 29, 31}))));
+}
+
+static inline vec_ushort8 vec_packs(vec_uint4 a, vec_uint4 b)
+{
+  vec_uint4 max = spu_splats((unsigned int)0x0000FFFF);
+  
+  return ((vec_ushort8)(spu_shuffle(spu_sel(a, max, spu_cmpgt(a, max)), 
+                                   spu_sel(b, max, spu_cmpgt(b, max)), 
+                                   ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
+                                                  18, 19, 22, 23, 26, 27, 30, 31}))));
+}  
+
+static inline vec_short8 vec_packs(vec_int4 a, vec_int4 b)
+{
+  vec_int4 max = spu_splats((signed int)0x00007FFF);
+  vec_int4 min = spu_splats((signed int)0xFFFF8000);
+  
+  return ((vec_short8)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, max)), spu_cmpgt(a, min)),
+                                  spu_sel(min, spu_sel(b, max, spu_cmpgt(b, max)), spu_cmpgt(b, min)),
+                                  ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
+                                                 18, 19, 22, 23, 26, 27, 30, 31}))));
+}  
+
+
+/* vec_packsu (vector pack saturate unsigned)
+ * ==========
+ */
+static inline vec_uchar16 vec_packsu(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((vec_uchar16)spu_shuffle(spu_or(a, (vec_ushort8)(spu_cmpgt(a, 255))),
+                                  spu_or(b, (vec_ushort8)(spu_cmpgt(b, 255))),
+                                  ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
+                                                 17, 19, 21, 23, 25, 27, 29, 31})));
+}
+
+static inline vec_uchar16 vec_packsu(vec_short8 a, vec_short8 b)
+{
+  vec_short8 max = spu_splats((signed short)0x00FF);
+  vec_short8 min = spu_splats((signed short)0x0000);
+  
+  return ((vec_uchar16)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, 255)), spu_cmpgt(a, 0)),
+                                   spu_sel(min, spu_sel(b, max, spu_cmpgt(b, 255)), spu_cmpgt(b, 0)),
+                                   ((vec_uchar16){ 1,  3,  5,  7,  9, 11, 13, 15,
+                                                  17, 19, 21, 23, 25, 27, 29, 31}))));
+
+  return (vec_packsu((vec_ushort8)(a), (vec_ushort8)(b)));
+}
+
+static inline vec_ushort8 vec_packsu(vec_uint4 a, vec_uint4 b)
+{
+  vec_uint4 max = spu_splats((unsigned int)0xFFFF);
+
+  return ((vec_ushort8)spu_shuffle(spu_or(a, (vec_uint4)(spu_cmpgt(a, max))),
+                                  spu_or(b, (vec_uint4)(spu_cmpgt(b, max))),
+                                  ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
+                                                 18, 19, 22, 23, 26, 27, 30, 31})));
+}
+
+static inline vec_ushort8 vec_packsu(vec_int4 a, vec_int4 b)
+{
+  vec_int4 max = spu_splats((signed int)0x0000FFFF);
+  vec_int4 min = spu_splats((signed int)0x00000000);
+  
+  return ((vec_ushort8)(spu_shuffle(spu_sel(min, spu_sel(a, max, spu_cmpgt(a, max)), spu_cmpgt(a, min)),
+                                   spu_sel(min, spu_sel(b, max, spu_cmpgt(b, max)), spu_cmpgt(b, min)),
+                                   ((vec_uchar16){ 2,  3,  6,  7, 10, 11, 14, 15,
+                                                  18, 19, 22, 23, 26, 27, 30, 31}))));
+}
+
+
+/* vec_perm (vector permute)
+ * ========
+ */
+static inline vec_uchar16 vec_perm(vec_uchar16 a, vec_uchar16 b, vec_uchar16 c)
+{
+  return (spu_shuffle(a, b, spu_and(c, 0x1F)));
+}
+
+static inline vec_char16 vec_perm(vec_char16 a, vec_char16 b, vec_uchar16 c)
+{
+  return ((vec_char16)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
+}
+
+static inline vec_ushort8 vec_perm(vec_ushort8 a, vec_ushort8 b, vec_uchar16 c)
+{
+  return ((vec_ushort8)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
+}
+
+static inline vec_short8 vec_perm(vec_short8 a, vec_short8 b, vec_uchar16 c)
+{
+  return ((vec_short8)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
+}
+
+static inline vec_uint4 vec_perm(vec_uint4 a, vec_uint4 b, vec_uchar16 c)
+{
+  return ((vec_uint4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
+}
+
+static inline vec_int4 vec_perm(vec_int4 a, vec_int4 b, vec_uchar16 c)
+{
+  return ((vec_int4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
+}
+
+static inline vec_float4 vec_perm(vec_float4 a, vec_float4 b, vec_uchar16 c)
+{
+  return ((vec_float4)(vec_perm((vec_uchar16)(a), (vec_uchar16)(b), c)));
+}
+
+
+/* vec_re (vector reciprocal estimate)
+ * ======
+ */
+#define vec_re(_a)     spu_re(_a)
+
+
+/* vec_rl (vector rotate left)
+ * ======
+ */
+static inline vec_uchar16 vec_rl(vec_uchar16 a, vec_uchar16 b)
+{
+  vec_ushort8 r1, r2;
+
+  r1 = spu_rl(spu_and((vec_ushort8)(a), 0xFF), (vec_short8)spu_and((vec_ushort8)(b), 7));
+  r2 = spu_rl(spu_and((vec_ushort8)(a), -256), (vec_short8)spu_and(spu_rlmask((vec_ushort8)(b), -8), 7));
+  return ((vec_uchar16)(spu_sel(spu_or(r2, spu_sl(r2, 8)), spu_or(r1, spu_rlmask(r1, -8)), spu_splats((unsigned short)0xFF))));
+}
+
+static inline vec_char16 vec_rl(vec_char16 a, vec_uchar16 b)
+{
+  return ((vec_char16)(vec_rl((vec_uchar16)(a), b)));
+}
+
+static inline vec_ushort8 vec_rl(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_rl(a, (vec_short8)(b)));
+}
+
+static inline vec_short8 vec_rl(vec_short8 a, vec_ushort8 b)
+{
+  return (spu_rl(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_rl(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_rl(a, (vec_int4)(b)));
+}
+
+static inline vec_int4 vec_rl(vec_int4 a, vec_uint4 b)
+{
+  return (spu_rl(a, (vec_int4)(b)));
+}
+
+
+/* vec_round (vector round)
+ * =========
+ */
+static inline vec_float4 vec_round(vec_float4 a)
+{
+  vec_float4 s_half, s_one, d;
+  vec_uint4 odd;
+  vec_uint4 msb = spu_splats((unsigned int)0x80000000);
+  vec_float4 half = spu_splats(0.5f);
+  vec_int4 exp;
+  vec_uint4 mask;
+
+  s_half = (vec_float4)(spu_sel((vec_uint4)(half), (vec_uint4)(a), msb));
+  a = spu_add(a, s_half);
+  s_one = spu_add(s_half, s_half);
+  exp  = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
+  mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
+  mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
+  mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
+
+  odd = spu_and((vec_uint4)(spu_convts(a, 0)), 1);
+  s_one = spu_andc(s_one, (vec_float4)spu_cmpeq(mask, 0));
+  s_one = spu_and(s_one, spu_and((vec_float4)spu_cmpeq(spu_and((vec_uint4)(a), mask), 0),
+                                (vec_float4)spu_cmpeq(odd, 1)));
+  d = spu_andc(a, (vec_float4)(mask));
+  d = spu_sub(d, s_one);
+  return (d);
+}
+
+/* vec_rsqrte (vector reciprocal square root estimate)
+ * ==========
+ */
+#define vec_rsqrte(_a) spu_rsqrte(_a)
+
+
+/* vec_sel (vector select)
+ * =======
+ */
+#define vec_sel(_a, _b, _c)    spu_sel(_a, _b, _c)
+
+
+/* vec_sl (vector shift left)
+ * ======
+ */
+static inline vec_uchar16 vec_sl(vec_uchar16 a, vec_uchar16 b)
+{
+  vec_ushort8 hi, lo;
+
+  lo = spu_and(spu_sl((vec_ushort8)(a), spu_and((vec_ushort8)(b), 7)), 0xFF);
+  hi = spu_sl(spu_and((vec_ushort8)(a), -256), spu_and(spu_rlmask((vec_ushort8)(b), -8), 7));
+
+  return ((vec_uchar16)(spu_or(hi, lo)));
+}
+
+static inline vec_char16 vec_sl(vec_char16 a, vec_uchar16 b)
+{
+  return ((vec_char16)(vec_sl((vec_uchar16)(a), b)));
+}
+
+static inline vec_ushort8 vec_sl(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_sl(a, spu_and(b, 15)));
+}
+
+static inline vec_short8 vec_sl(vec_short8 a, vec_ushort8 b)
+{
+  return (spu_sl(a, spu_and((vec_ushort8)(b), 15)));
+}
+
+static inline vec_uint4 vec_sl(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_sl(a, spu_and(b, 31)));
+}
+
+static inline vec_int4 vec_sl(vec_int4 a, vec_uint4 b)
+{
+  return (spu_sl(a, spu_and(b, 31)));
+}
+
+
+/* vec_sld (vector shift left double)
+ * =======
+ */
+#define vec_sld(_a, _b, _c)    spu_shuffle(_a, _b, ((vec_uchar16){ 0+(_c),  1+(_c),  2+(_c),  3+(_c),  \
+                                                                   4+(_c),  5+(_c),  6+(_c),  7+(_c),  \
+                                                                   8+(_c),  9+(_c), 10+(_c), 11+(_c),  \
+                                                                  12+(_c), 13+(_c), 14+(_c), 15+(_c)}))
+
+
+/* vec_sll (vector shift left long)
+ * =======
+ */
+#define vec_sll(_a, _b)                spu_slqw(_a, spu_extract((vec_uint4)(_b), 0))
+
+
+/* vec_slo (vector shift left by octet)
+ * =======
+ */
+#define vec_slo(_a, _b)                spu_slqwbytebc(_a, spu_extract((vec_uint4)(_b), 3) & 0x7F)
+
+
+/* vec_splat (vector splat)
+ * =========
+ */
+#define vec_splat(_a, _b)      spu_splats(spu_extract(_a, _b))
+
+
+/* vec_splat_s8 (vector splat signed byte)
+ * ============
+ */
+#define vec_splat_s8(_a)       spu_splats((signed char)(_a))
+
+
+/* vec_splat_s16 (vector splat signed half-word)
+ * =============
+ */
+#define vec_splat_s16(_a)      spu_splats((signed short)(_a))
+
+
+/* vec_splat_s32 (vector splat signed word)
+ * =============
+ */
+#define vec_splat_s32(_a)      spu_splats((signed int)(_a))
+
+
+/* vec_splat_u8 (vector splat unsigned byte)
+ * ============
+ */
+#define vec_splat_u8(_a)       spu_splats((unsigned char)(_a))
+
+
+/* vec_splat_u16 (vector splat unsigned half-word)
+ * =============
+ */
+#define vec_splat_u16(_a)      spu_splats((unsigned short)(_a))
+
+
+/* vec_splat_u32 (vector splat unsigned word)
+ * =============
+ */
+#define vec_splat_u32(_a)      spu_splats((unsigned int)(_a))
+
+
+/* vec_sr (vector shift right)
+ * ======
+ */
+static inline vec_uchar16 vec_sr(vec_uchar16 a, vec_uchar16 b)
+{
+  vec_ushort8 hi, lo;
+
+  lo = spu_rlmask(spu_and((vec_ushort8)(a), 0xFF), spu_sub(0, (vec_short8)(spu_and((vec_ushort8)(b), 7))));
+  hi = spu_and(spu_rlmask((vec_ushort8)(a), spu_sub(0, (vec_short8)(spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)))), -256);
+
+  return ((vec_uchar16)(spu_or(hi, lo)));
+}
+
+static inline vec_char16 vec_sr(vec_char16 a, vec_uchar16 b)
+{
+  return ((vec_char16)(vec_sr((vec_uchar16)(a), b)));
+}
+
+static inline vec_ushort8 vec_sr(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_rlmask(a, spu_sub(0, (vec_short8)(spu_and(b, 15)))));
+}
+
+static inline vec_short8 vec_sr(vec_short8 a, vec_ushort8 b)
+{
+  return ((vec_short8)(vec_sr((vec_ushort8)(a), b)));
+}
+
+static inline vec_uint4 vec_sr(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_rlmask(a, spu_sub(0, (vec_int4)(spu_and(b, 31)))));
+}
+
+static inline vec_int4 vec_sr(vec_int4 a, vec_uint4 b)
+{
+  return ((vec_int4)(vec_sr((vec_uint4)(a), b)));
+}
+
+
+/* vec_sra (vector shift right algebraic)
+ * =======
+ */
+static inline vec_char16 vec_sra(vec_char16 a, vec_uchar16 b)
+{
+  vec_short8 hi, lo;
+
+  lo = spu_and(spu_rlmaska(spu_extend(a), spu_sub(0, (vec_short8)(spu_and((vec_ushort8)(b), 7)))), 0xFF);
+  hi = spu_and(spu_rlmaska((vec_short8)(a), spu_sub(0, (vec_short8)(spu_and(spu_rlmask((vec_ushort8)(b), -8), 7)))), -256);
+
+  return ((vec_char16)(spu_or(hi, lo)));
+}
+
+static inline vec_uchar16 vec_sra(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((vec_uchar16)(vec_sra((vec_char16)(a), b)));
+}
+
+static inline vec_short8 vec_sra(vec_short8 a, vec_ushort8 b)
+{
+  return (spu_rlmaska(a, spu_sub(0, (vec_short8)(spu_and(b, 15)))));
+}
+
+static inline vec_ushort8 vec_sra(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((vec_ushort8)(vec_sra((vec_short8)(a), b)));
+}
+
+static inline vec_int4 vec_sra(vec_int4 a, vec_uint4 b)
+{
+  return (spu_rlmaska(a, spu_sub(0, (vec_int4)(spu_and(b, 31)))));
+}
+
+static inline vec_uint4 vec_sra(vec_uint4 a, vec_uint4 b)
+{
+  return ((vec_uint4)(vec_sra((vec_int4)(a), b)));
+}
+
+
+/* vec_srl (vector shift right long)
+ * =======
+ */
+#define vec_srl(_a, _b)                spu_rlmaskqw(_a, 0-spu_extract((vec_int4)(_b), 3))
+
+
+/* vec_sro (vector shift right by octet)
+ * =======
+ */
+#define vec_sro(_a, _b)                spu_rlmaskqwbyte(_a, 0 - ((spu_extract((vec_int4)(_b), 3) >> 3) & 0xF))
+
+/* vec_st (vector store indexed)
+ * ======
+ */
+static inline void vec_st(vec_uchar16 a, int b, unsigned char *c)
+{
+  *((vec_uchar16 *)(c+b)) = a;
+}
+
+static inline void vec_st(vec_uchar16 a, int b, vec_uchar16 *c)
+{
+  *((vec_uchar16 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_char16 a, int b, signed char *c)
+{
+  *((vec_char16 *)(c+b)) = a;
+}
+
+static inline void vec_st(vec_char16 a, int b, vec_char16 *c)
+{
+  *((vec_char16 *)((signed char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_bchar16 a, int b, signed char *c)
+{
+  *((vec_bchar16 *)((signed char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_ushort8 a, int b, unsigned short *c)
+{
+  *((vec_ushort8 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_ushort8 a, int b, vec_ushort8 *c)
+{
+  *((vec_ushort8 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_short8 a, int b, signed short *c)
+{
+  *((vec_short8 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_short8 a, int b, vec_short8 *c)
+{
+  *((vec_short8 *)((signed char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_bshort8 a, int b, signed short *c)
+{
+  *((vec_bshort8 *)((signed char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_uint4 a, int b, unsigned int *c)
+{
+  *((vec_uint4 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_uint4 a, int b, vec_uint4 *c)
+{
+  *((vec_uint4 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_int4 a, int b, signed int *c)
+{
+  *((vec_int4 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_int4 a, int b, vec_int4 *c)
+{
+  *((vec_int4 *)((signed char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_bint4 a, int b, signed int *c)
+{
+  *((vec_bint4 *)((signed char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_float4 a, int b, float *c)
+{
+  *((vec_float4 *)((unsigned char *)(c)+b)) = a;
+}
+
+static inline void vec_st(vec_float4 a, int b, vec_float4 *c)
+{
+  *((vec_float4 *)((unsigned char *)(c)+b)) = a;
+}
+
+
+/* vec_ste (vector store element indexed)
+ * =======
+ */
+static inline void vec_ste(vec_uchar16 a, int b, unsigned char *c)
+{
+  unsigned char *ptr;
+
+  ptr = c + b;
+  *ptr = spu_extract(a, (int)(ptr) & 15);
+}
+
+static inline void vec_ste(vec_char16 a, int b, signed char *c)
+{
+  vec_ste((vec_uchar16)(a), b, (unsigned char *)(c));
+}
+
+static inline void vec_ste(vec_bchar16 a, int b, signed char *c)
+{
+  vec_ste((vec_uchar16)(a), b, (unsigned char *)(c));
+}
+
+static inline void vec_ste(vec_ushort8 a, int b, unsigned short *c)
+{
+  unsigned short *ptr;
+
+  ptr = (unsigned short *)(((unsigned int)(c) + b) & ~1);
+  *ptr = spu_extract(a, ((int)(ptr) >> 1) & 7);
+}
+
+static inline void vec_ste(vec_short8 a, int b, signed short *c)
+{
+  vec_ste((vec_ushort8)(a), b, (unsigned short *)(c));
+}
+
+static inline void vec_ste(vec_bshort8 a, int b, signed short *c)
+{
+  vec_ste((vec_ushort8)(a), b, (unsigned short *)(c));
+}
+
+static inline void vec_ste(vec_uint4 a, int b, unsigned int *c)
+{
+  unsigned int *ptr;
+
+  ptr = (unsigned int *)(((unsigned int)(c) + b) & ~3);
+  *ptr = spu_extract(a, ((int)(ptr) >> 2) & 3);
+}
+
+static inline void vec_ste(vec_int4 a, int b, signed int *c)
+{
+  vec_ste((vec_uint4)(a), b, (unsigned int *)(c));
+}
+
+static inline void vec_ste(vec_bint4 a, int b, signed int *c)
+{
+  vec_ste((vec_uint4)(a), b, (unsigned int *)(c));
+}
+
+static inline void vec_ste(vec_float4 a, int b, float *c)
+{
+  vec_ste((vec_uint4)(a), b, (unsigned int *)(c));
+}
+
+
+/* vec_stl (vector store indexed LRU)
+ * =======
+ */
+#define vec_stl(_a, _b, _c)            vec_st(_a, _b, _c)
+
+
+/* vec_sub (vector subtract)
+ * =======
+ */
+static inline vec_uchar16 vec_sub(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((vec_uchar16)(spu_sel(spu_sub((vec_ushort8)(a), (vec_ushort8)(b)),
+                               spu_sub(spu_and((vec_ushort8)(a), -256), spu_and((vec_ushort8)(b), -256)),
+                               spu_splats((unsigned short)0xFF00))));
+}
+
+static inline vec_char16 vec_sub(vec_char16 a, vec_char16 b)
+{
+  return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b))));
+}
+
+static inline vec_char16 vec_sub(vec_bchar16 a, vec_char16 b)
+{
+  return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b))));
+}
+
+static inline vec_char16 vec_sub(vec_char16 a, vec_bchar16 b)
+{
+  return ((vec_char16)(vec_sub((vec_uchar16)(a), (vec_uchar16)(b))));
+}
+
+static inline vec_ushort8 vec_sub(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_sub(a, b));
+}
+
+static inline vec_short8 vec_sub(vec_short8 a, vec_short8 b)
+{
+  return (spu_sub(a, b));
+}
+
+static inline vec_short8 vec_sub(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_sub((vec_short8)(a), b));
+}
+
+static inline vec_short8 vec_sub(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_sub(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_sub(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_sub(a, b));
+}
+
+static inline vec_int4 vec_sub(vec_int4 a, vec_int4 b)
+{
+  return (spu_sub(a, b));
+}
+
+static inline vec_int4 vec_sub(vec_bint4 a, vec_int4 b)
+{
+  return (spu_sub((vec_int4)(a), b));
+}
+
+static inline vec_int4 vec_sub(vec_int4 a, vec_bint4 b)
+{
+  return (spu_sub(a, (vec_int4)(b)));
+}
+
+static inline vec_float4 vec_sub(vec_float4 a, vec_float4 b)
+{
+  return (spu_sub(a, b));
+}
+
+
+/* vec_subc (vector subtract carryout)
+ * ========
+ */
+#define vec_subc(_a, _b)       spu_genb(_a, _b)
+
+
+/* vec_subs (vector subtract saturate)
+ * ========
+ */
+static inline vec_uchar16 vec_subs(vec_uchar16 a, vec_uchar16 b)
+{
+  vec_ushort8 s1, s2;
+  vec_uchar16 s, d;
+
+  s1 = spu_sub(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8));
+  s2 = spu_sub(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF));
+  s  = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){0, 16,  2, 18,  4, 20,  6, 22,
+                                                       8, 24, 10, 26, 12, 28, 14, 30})));
+  d  = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
+                                                       9, 25, 11, 27, 13, 29, 15, 31})));
+  return (spu_andc(d, s));
+}
+
+static inline vec_char16 vec_subs(vec_char16 a, vec_char16 b)
+{
+  vec_ushort8 s1, s2;
+  vec_uchar16 s, d;
+
+  s1 = spu_sub(spu_rlmask((vec_ushort8)(a), -8), spu_rlmask((vec_ushort8)(b), -8));
+  s2 = spu_sub(spu_and((vec_ushort8)(a), 0xFF), spu_and((vec_ushort8)(b), 0xFF));
+  s  = (vec_uchar16)(spu_shuffle(s1, s2, ((vec_uchar16){1, 17,  3, 19,  5, 21,  7, 23,
+                                                       9, 25, 11, 27, 13, 29, 15, 31})));
+  d  = spu_sel(s, spu_splats((unsigned char)0x7F), spu_cmpgt(spu_nor((vec_uchar16)(a), spu_nand(s, (vec_uchar16)(b))), 0x7F));
+  d  = spu_sel(d, spu_splats((unsigned char)0x80), spu_cmpgt(spu_and((vec_uchar16)(a), spu_nor(s, (vec_uchar16)(b))), 0x7F));
+  
+  return ((vec_char16)(d));
+}
+
+static inline vec_char16 vec_subs(vec_bchar16 a, vec_char16 b)
+{
+  return (vec_subs((vec_char16)(a), b));
+}
+
+static inline vec_char16 vec_subs(vec_char16 a, vec_bchar16 b)
+{
+  return (vec_subs(a, (vec_char16)(b)));
+}
+
+static inline vec_ushort8 vec_subs(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_andc(spu_sub(a, b), spu_cmpgt(b, a)));
+}
+
+static inline vec_short8 vec_subs(vec_short8 a, vec_short8 b)
+{
+  vec_short8 s;
+  vec_short8 d;
+  
+  s = spu_sub(a, b);
+  d = spu_sel(s, spu_splats((signed short)0x7FFF), (vec_ushort8)(spu_rlmaska(spu_nor(a, spu_nand(s, b)), -15)));
+  d = spu_sel(d, spu_splats((signed short)0x8000), (vec_ushort8)(spu_rlmaska(spu_and(a, spu_nor(s, b)), -15)));
+
+  return (d);
+}
+
+static inline vec_short8 vec_subs(vec_bshort8 a, vec_short8 b)
+{
+  return ((vec_short8)(vec_subs((vec_short8)(a), b)));
+}
+
+static inline vec_short8 vec_subs(vec_short8 a, vec_bshort8 b)
+{
+  return ((vec_short8)(vec_subs(a, (vec_short8)(b))));
+}
+
+static inline vec_uint4 vec_subs(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_andc(spu_sub(a, b), spu_cmpgt(b, a)));
+}
+
+static inline vec_int4 vec_subs(vec_int4 a, vec_int4 b)
+{
+  vec_int4 s;
+  vec_int4 d;
+  
+  s = spu_sub(a, b);
+  d = spu_sel(s, spu_splats((signed int)0x7FFFFFFF), (vec_uint4)(spu_rlmaska(spu_nor(a, spu_nand(s, b)), -31)));
+  d = spu_sel(d, spu_splats((signed int)0x80000000), (vec_uint4)(spu_rlmaska(spu_and(a, spu_nor(s, b)), -31)));
+
+  return (d);
+}
+
+static inline vec_int4 vec_subs(vec_bint4 a, vec_int4 b)
+{
+  return ((vec_int4)(vec_subs((vec_int4)(a), b)));
+}
+
+static inline vec_int4 vec_subs(vec_int4 a, vec_bint4 b)
+{
+  return ((vec_int4)(vec_subs(a, (vec_int4)(b))));
+}
+
+
+/* vec_sum4s (vector sum across partial (1/4) staturated)
+ * =========
+ */
+static inline vec_uint4 vec_sum4s(vec_uchar16 a, vec_uint4 b)
+{
+  vec_uint4 a01_23, a0123;
+
+  a01_23 = (vec_uint4)(spu_add(spu_rlmask((vec_ushort8)(a), -8),
+                              spu_and((vec_ushort8)(a), 0xFF)));
+  a0123 = spu_add(spu_rlmask(a01_23, -16), spu_and(a01_23, 0x1FF));
+  return (vec_adds(a0123, b));
+}
+
+static inline vec_int4 vec_sum4s(vec_char16 a, vec_int4 b)
+{
+  vec_int4 a01_23, a0123;
+
+  a01_23 = (vec_int4)(spu_add(spu_rlmaska((vec_short8)(a), -8),
+                             spu_extend(a)));
+  a0123 = spu_add(spu_rlmaska(a01_23, -16), spu_extend((vec_short8)(a01_23)));
+  return (vec_adds(a0123, b));
+}
+
+static inline vec_int4 vec_sum4s(vec_short8 a, vec_int4 b)
+{
+  vec_int4 a0123;
+
+  a0123 = spu_add(spu_rlmaska((vec_int4)(a), -16), spu_extend(a));
+  return (vec_adds(a0123, b));
+}
+
+
+/* vec_sum2s (vector sum across partial (1/2) staturated)
+ * =========
+ */
+static inline vec_int4 vec_sum2s(vec_int4 a, vec_int4 b)
+{
+  vec_int4 c, d;
+  vec_int4 sign1, sign2, sign3;
+  vec_int4 carry, sum_l, sum_h, sat, sat_val;
+
+  sign1 = spu_rlmaska(a, -31);
+  sign2 = spu_rlmaska(b, -31);
+
+  c = spu_rlqwbyte(a, -4);
+  sign3 = spu_rlqwbyte(sign1, -4);
+  
+  carry = spu_genc(a, b);
+  sum_l = spu_add(a, b);
+  sum_h = spu_addx(sign1, sign2, carry);
+
+  carry = spu_genc(sum_l, c);
+  sum_l = spu_add(sum_l, c);
+  sum_h = spu_addx(sum_h, sign3, carry);
+  
+  sign1 = spu_rlmaska(sum_l, -31);
+  sign2 = spu_rlmaska(sum_h, -31);
+
+  sat_val = spu_xor(sign2, spu_splats((signed int)0x7FFFFFFF));
+
+  sat = spu_orc(spu_xor(sign1, sign2), (vec_int4)spu_cmpeq(sum_h, sign2));
+
+  d = spu_and(spu_sel(sum_l, sat_val, (vec_uint4)(sat)), (vec_int4){0, -1, 0, -1});
+
+  return (d);
+}
+
+
+/* vec_sums (vector sum staturated)
+ * ========
+ */
+static inline vec_int4 vec_sums(vec_int4 a, vec_int4 b)
+{
+  vec_int4 a0, a1, a2, c0, c1, c2, d;
+  vec_int4 sign_a, sign_b, sign_l, sign_h;
+  vec_int4 sum_l, sum_h, sat, sat_val;
+
+  sign_a = spu_rlmaska(a, -31);
+  sign_b = spu_rlmaska(b, -31);
+
+  a0 = spu_rlqwbyte(a, -12);
+  a1 = spu_rlqwbyte(a, -8);
+  a2 = spu_rlqwbyte(a, -4);
+
+  sum_l = spu_add(a, b);
+  sum_h = spu_addx(sign_a, sign_b, spu_genc(a, b));
+  
+  c2 = spu_genc(sum_l, a2);
+  sum_l = spu_add(sum_l, a2);
+  sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -4), c2);
+
+  c1 = spu_genc(sum_l, a1);
+  sum_l = spu_add(sum_l, a1);
+  sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -8), c1);
+
+  c0 = spu_genc(sum_l, a0);
+  sum_l = spu_add(sum_l, a0);
+  sum_h = spu_addx(sum_h, spu_rlqwbyte(sign_a, -12), c0);
+
+  sign_l = spu_rlmaska(sum_l, -31);
+  sign_h = spu_rlmaska(sum_h, -31);
+
+  sat_val = spu_xor(sign_h, spu_splats((signed int)0x7FFFFFFF));
+
+  sat = spu_orc(spu_xor(sign_l, sign_h), (vec_int4)spu_cmpeq(sum_h, sign_h));
+
+  d = spu_and(spu_sel(sum_l, sat_val, (vec_uint4)(sat)), ((vec_int4){0, 0, 0, -1}));
+
+  return (d);
+}
+
+
+/* vec_trunc (vector truncate) 
+ * =========
+ */
+static inline vec_float4 vec_trunc(vec_float4 a)
+{
+  vec_int4 exp;
+  vec_uint4 mask;
+
+  exp  = spu_sub(127, (vec_int4)(spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF)));
+  mask = spu_rlmask(spu_splats((unsigned int)0x7FFFFF), exp);
+  mask = spu_sel(spu_splats((unsigned int)0), mask, spu_cmpgt(exp, -31));
+  mask = spu_or(mask, spu_xor((vec_uint4)(spu_rlmaska(spu_add(exp, -1), -31)), -1));
+  return (spu_andc(a, (vec_float4)(mask)));
+}
+
+/* vec_unpackh (vector unpack high element) 
+ * ===========
+ */
+static inline vec_short8 vec_unpackh(vec_char16 a)
+{
+  return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 1, 1, 2, 2, 3, 3, 
+                                                     4, 4, 5, 5, 6, 6, 7, 7}))));
+}
+
+static inline vec_bshort8 vec_unpackh(vec_bchar16 a)
+{
+  return ((vec_bshort8)(vec_unpackh((vec_char16)(a))));
+}
+
+static inline vec_int4 vec_unpackh(vec_short8 a)
+{
+  return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 0, 1, 0, 0, 2, 3, 
+                                                     0, 0, 4, 5, 0, 0, 6, 7}))));
+}
+
+#ifdef SUPPORT_UNPACK_PIXEL
+/* Due to type conflicts, unpacking of pixel types and boolean shorts
+ * can not simultaneously be supported. By default, the boolean short is
+ * supported.
+ */
+static inline vec_uint4 vec_unpackh(vec_pixel8 a)
+{
+  vec_ushort8 p1, p2;
+
+  p1 = spu_shuffle((vec_ushort8)(spu_rlmaska((vec_short8)(a.p), -7)),
+                  spu_and((vec_ushort8)(a.p), 0x1F),
+                  ((vec_uchar16){ 0, 128, 128, 17,  2, 128, 128, 19,
+                                  4, 128, 128, 21,  6, 128, 128, 23}));
+  p2 = spu_shuffle(spu_and(spu_rlmask((vec_ushort8)(a.p), -5), 0x1F),
+                  spu_and(spu_rlmask((vec_ushort8)(a.p), -10), 0x1F),
+                  ((vec_uchar16){ 128,  17, 1, 128, 128,  19, 3, 128,
+                                  128,  21, 5, 128, 128,  23, 7, 128}));
+  return ((vec_uint4)(spu_or(p1, p2)));
+}
+
+#else
+
+static inline vec_bint4 vec_unpackh(vec_bshort8 a)
+{
+  return ((vec_bint4)(vec_unpackh((vec_short8)(a))));
+}
+#endif
+
+
+
+
+
+/* vec_unpackl (vector unpack low element) 
+ * ===========
+ */
+static inline vec_short8 vec_unpackl(vec_char16 a)
+{
+  return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){8, 8, 9, 9, 10, 10, 11, 11,
+                                                     12, 12, 13, 13, 14, 14, 15, 15}))));
+}
+
+static inline vec_bshort8 vec_unpackl(vec_bchar16 a)
+{
+  return ((vec_bshort8)(vec_unpackl((vec_char16)(a))));
+}
+
+
+static inline vec_int4 vec_unpackl(vec_short8 a)
+{
+  return (spu_extend(spu_shuffle(a, a, ((vec_uchar16){0, 0, 8, 9, 0, 0, 10, 11, 
+                                                     0, 0,12,13, 0, 0, 14, 15}))));
+}
+
+
+#ifdef SUPPORT_UNPACK_PIXEL
+/* Due to type conflicts, unpacking of pixel types and boolean shorts
+ * can not simultaneously be supported. By default, the boolean short is
+ * supported.
+ */
+static inline vec_uint4 vec_unpackl(vec_pixel8 a)
+{
+  vec_ushort8 p1, p2;
+
+  p1 = spu_shuffle((vec_ushort8)(spu_rlmaska((vec_short8)(a), -7)),
+                  spu_and((vec_ushort8)(a), 0x1F),
+                  ((vec_uchar16){ 8, 128, 128, 25,  10, 128, 128, 27,
+                                 12, 128, 128, 29,  14, 128, 128, 31}));
+  p2 = spu_shuffle(spu_and(spu_rlmask((vec_ushort8)(a), -5), 0x1F),
+                  spu_and(spu_rlmask((vec_ushort8)(a), -10), 0x1F),
+                  ((vec_uchar16){ 128, 25,  9, 128, 128, 27, 11, 128,
+                                  128, 29, 13, 128, 128, 31, 15, 128}));
+  return ((vec_uint4)(spu_or(p1, p2)));
+}
+
+#else
+
+static inline vec_bint4 vec_unpackl(vec_bshort8 a)
+{
+  return ((vec_bint4)(vec_unpackl((vec_short8)(a))));
+
+}
+#endif
+
+
+
+/* vec_xor (vector logical xor)
+ * ======
+ */
+static inline vec_uchar16 vec_xor(vec_uchar16 a, vec_uchar16 b)
+{
+  return (spu_xor(a, b));
+}
+
+static inline vec_char16 vec_xor(vec_char16 a, vec_char16 b)
+{
+  return (spu_xor(a, b));
+}
+
+static inline vec_char16 vec_xor(vec_bchar16 a, vec_char16 b)
+{
+  return (spu_xor((vec_char16)(a), b));
+}
+
+static inline vec_char16 vec_xor(vec_char16 a, vec_bchar16 b)
+{
+  return (spu_xor(a, (vec_char16)(b)));
+}
+
+static inline vec_ushort8 vec_xor(vec_ushort8 a, vec_ushort8 b)
+{
+  return (spu_xor(a, b));
+}
+
+static inline vec_short8 vec_xor(vec_short8 a, vec_short8 b)
+{
+  return (spu_xor(a, b));
+}
+
+static inline vec_short8 vec_xor(vec_bshort8 a, vec_short8 b)
+{
+  return (spu_xor((vec_short8)(a), b));
+}
+
+static inline vec_short8 vec_xor(vec_short8 a, vec_bshort8 b)
+{
+  return (spu_xor(a, (vec_short8)(b)));
+}
+
+static inline vec_uint4 vec_xor(vec_uint4 a, vec_uint4 b)
+{
+  return (spu_xor(a, b));
+}
+
+static inline vec_int4 vec_xor(vec_int4 a, vec_int4 b)
+{
+  return (spu_xor(a, b));
+}
+
+static inline vec_int4 vec_xor(vec_bint4 a, vec_int4 b)
+{
+  return (spu_xor((vec_int4)(a), b));
+}
+
+static inline vec_int4 vec_xor(vec_int4 a, vec_bint4 b)
+{
+  return (spu_xor(a, (vec_int4)(b)));
+}
+
+static inline vec_float4 vec_xor(vec_float4 a, vec_float4 b)
+{
+  return (spu_xor(a, b));
+}
+
+static inline vec_float4 vec_xor(vec_bint4 a, vec_float4 b)
+{
+  return (spu_xor((vec_float4)(a),b));
+}
+
+static inline vec_float4 vec_xor(vec_float4 a, vec_bint4 b)
+{
+  return (spu_xor(a, (vec_float4)(b)));
+}
+
+/************************************************************************
+ *                        PREDICATES
+ ************************************************************************/
+
+/* vec_all_eq (all elements equal)
+ * ==========
+ */
+static inline int vec_all_eq(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_eq(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_eq(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_eq(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) == 0xFFFF));
+}
+
+static inline int vec_all_eq(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFF));
+}
+
+static inline int vec_all_eq(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xFF));
+}
+
+static inline int vec_all_eq(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) == 0xFF));
+}
+
+static inline int vec_all_eq(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) == 0xFF));
+}
+
+static inline int vec_all_eq(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF));
+}
+
+static inline int vec_all_eq(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF));
+}
+
+static inline int vec_all_eq(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) == 0xF));
+}
+
+static inline int vec_all_eq(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) == 0xF));
+}
+
+static inline int vec_all_eq(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0xF));
+}
+
+
+/* vec_all_ge (all elements greater than or equal)
+ * ==========
+ */
+static inline int vec_all_ge(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+static inline  int vec_all_ge(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) == 0));
+}
+
+static inline int vec_all_ge(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+
+/* vec_all_gt (all elements greater than)
+ * ==========
+ */
+static inline int vec_all_gt(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_gt(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_gt(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_gt(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) == 0xFFFF));
+}
+
+static inline int vec_all_gt(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFF));
+}
+
+static inline int vec_all_gt(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xFF));
+}
+
+static inline int vec_all_gt(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) == 0xFF));
+}
+
+static inline int vec_all_gt(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) == 0xFF));
+}
+
+static inline int vec_all_gt(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
+}
+
+static inline int vec_all_gt(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
+}
+
+static inline int vec_all_gt(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) == 0xF));
+}
+
+static inline int vec_all_gt(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) == 0xF));
+}
+
+static inline int vec_all_gt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
+}
+
+
+/* vec_all_in (all elements in bounds)
+ * ==========
+ */
+static inline int vec_all_in(vec_float4 a, vec_float4 b)
+{
+  return (spu_extract(spu_gather(spu_nor(spu_cmpabsgt(a, b), (vec_uint4)(spu_rlmaska((vec_int4)(b), -31)))), 0) == 0xF);
+}
+
+
+/* vec_all_le (all elements less than or equal)
+ * ==========
+ */
+static inline int vec_all_le(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) == 0));
+}
+
+static inline int vec_all_le(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) == 0));
+}
+
+static inline int vec_all_le(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) == 0));
+}
+
+static inline int vec_all_le(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) == 0));
+}
+
+static inline int vec_all_le(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+
+/* vec_all_lt (all elements less than)
+ * ==========
+ */
+static inline int vec_all_lt(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_lt(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_lt(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) == 0xFFFF));
+}
+
+static inline int vec_all_lt(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) == 0xFFFF));
+}
+
+static inline int vec_all_lt(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFF));
+}
+
+static inline int vec_all_lt(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xFF));
+}
+
+static inline int vec_all_lt(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) == 0xFF));
+}
+
+static inline int vec_all_lt(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) == 0xFF));
+}
+
+static inline int vec_all_lt(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
+}
+
+static inline int vec_all_lt(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
+}
+
+static inline int vec_all_lt(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) == 0xF));
+}
+
+static inline int vec_all_lt(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) == 0xF));
+}
+
+static inline int vec_all_lt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
+}
+
+
+/* vec_all_nan (all elements not a number)
+ * ===========
+ */
+static inline int vec_all_nan(vec_float4 a)
+{
+  vec_uint4 exp, man;
+  vec_uint4 exp_mask = spu_splats((unsigned int)0x7F800000);
+
+  exp = spu_and((vec_uint4)(a), exp_mask);
+  man = spu_and((vec_uint4)(a), spu_splats((unsigned int)0x007FFFFF));
+  return ((int)(spu_extract(spu_gather(spu_andc(spu_cmpeq(exp, exp_mask), 
+                                               spu_cmpeq(man, 0))), 0) == 0xF));
+}
+
+#define vec_all_nan(_a)                (0)
+
+
+/* vec_all_ne (all elements not equal)
+ * ==========
+ */
+static inline int vec_all_ne(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) == 0));
+}
+
+static inline int vec_all_ne(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) == 0));
+}
+
+
+/* vec_all_nge (all elements not greater than or eqaul)
+ * ===========
+ */
+static inline int vec_all_nge(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0xF));
+}
+
+
+/* vec_all_ngt (all elements not greater than)
+ * ===========
+ */
+static inline int vec_all_ngt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0));
+}
+
+
+/* vec_all_nle (all elements not less than or equal)
+ * ===========
+ */
+static inline int vec_all_nle(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) == 0xF));
+}
+
+
+/* vec_all_nlt (all elements not less than)
+ * ===========
+ */
+static inline int vec_all_nlt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) == 0));
+}
+
+
+/* vec_all_numeric (all elements numeric)
+ * ===========
+ */
+static inline int vec_all_numeric(vec_float4 a)
+{
+  vec_uint4 exp;
+
+  exp = spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF);
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(exp, 255)), 0) == 0));
+}
+
+
+
+/* vec_any_eq (any elements equal)
+ * ==========
+ */
+static inline int vec_any_eq(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) != 0));
+}
+
+static inline int vec_any_eq(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0)));
+}
+
+static inline int vec_any_eq(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0)));
+}
+
+static inline int vec_any_eq(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq((vec_int4)(a), b), -31)), 0)));
+}
+
+static inline int vec_any_eq(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, (vec_int4)(b)), -31)), 0)));
+}
+
+static inline int vec_any_eq(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpeq(a, b), -31)), 0)));
+}
+
+/* vec_any_ge (any elements greater than or equal)
+ * ==========
+ */
+static inline int vec_any_ge(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ge(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ge(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ge(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ge(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFF));
+}
+
+static inline int vec_any_ge(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xFF));
+}
+
+static inline int vec_any_ge(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) != 0xFF));
+}
+
+static inline int vec_any_ge(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) != 0xFF));
+}
+
+static inline int vec_any_ge(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
+}
+
+static inline int vec_any_ge(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
+}
+
+static inline int vec_any_ge(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_int4)(a))), 0) != 0xF));
+}
+
+static inline int vec_any_ge(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(b), a)), 0) != 0xF));
+}
+
+static inline int vec_any_ge(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
+}
+
+
+/* vec_any_gt (any elements greater than)
+ * ==========
+ */
+static inline int vec_any_gt(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
+}
+
+static inline int vec_any_gt(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
+}
+
+static inline int vec_any_gt(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) != 0));
+}
+
+static inline int vec_any_gt(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) != 0));
+}
+
+static inline int vec_any_gt(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
+}
+
+static inline int vec_any_gt(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
+}
+
+static inline int vec_any_gt(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) != 0));
+}
+
+static inline int vec_any_gt(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) != 0));
+}
+
+
+static inline int vec_any_gt(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0)));
+}
+
+static inline int vec_any_gt(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0)));
+}
+
+static inline int vec_any_gt(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt((vec_int4)(a), b), -31)), 0)));
+}
+
+static inline int vec_any_gt(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, (vec_int4)(b)), -31)), 0)));
+}
+
+static inline int vec_any_gt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(a, b), -31)), 0)));
+}
+
+/* vec_any_le (any elements less than or equal)
+ * ==========
+ */
+static inline int vec_any_le(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_le(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_le(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(a), b)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_le(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_char16)(b))), 0) != 0xFFFF));
+}
+
+static inline int vec_any_le(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFF));
+}
+
+static inline int vec_any_le(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xFF));
+}
+
+static inline int vec_any_le(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(a), b)), 0) != 0xFF));
+}
+
+static inline int vec_any_le(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_short8)(b))), 0) != 0xFF));
+}
+
+static inline int vec_any_le(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
+}
+
+static inline int vec_any_le(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
+}
+
+static inline int vec_any_le(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_int4)(a), b)), 0) != 0xF));
+}
+
+static inline int vec_any_le(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, (vec_int4)(b))), 0) != 0xF));
+}
+
+static inline int vec_any_le(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
+}
+
+
+/* vec_any_lt (any elements less than)
+ * ==========
+ */
+static inline int vec_any_lt(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_char16)(a))), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_char16)(b), a)), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, (vec_short8)(a))), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt((vec_short8)(b), a)), 0) != 0));
+}
+
+static inline int vec_any_lt(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
+}
+
+static inline int vec_any_lt(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
+}
+
+static inline int vec_any_lt(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, (vec_int4)(a)), -31)), 0)));
+}
+
+static inline int vec_any_lt(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt((vec_int4)(b), a), -31)), 0)));
+}
+
+static inline int vec_any_lt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
+}
+
+/* vec_any_nan (any elements not a number)
+ * ===========
+ */
+static inline int vec_any_nan(vec_float4 a)
+{
+  vec_uint4 exp, man;
+  vec_uint4 exp_mask = spu_splats((unsigned int)0x7F800000);
+
+  exp = spu_and((vec_uint4)(a), exp_mask);
+  man = spu_and((vec_uint4)(a), spu_splats((unsigned int)0x007FFFFF));
+  return ((int)(spu_extract(spu_gather(spu_andc(spu_cmpeq(exp, exp_mask), 
+                                               spu_cmpeq(man, 0))), 0) != 0));
+}
+
+
+/* vec_any_ne (any elements not equal)
+ * ==========
+ */
+static inline int vec_any_ne(vec_uchar16 a, vec_uchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ne(vec_char16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ne(vec_bchar16 a, vec_char16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_char16)(a), b)), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ne(vec_char16 a, vec_bchar16 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_char16)(b))), 0) != 0xFFFF));
+}
+
+static inline int vec_any_ne(vec_ushort8 a, vec_ushort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFF));
+}
+
+static inline int vec_any_ne(vec_short8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xFF));
+}
+
+static inline int vec_any_ne(vec_bshort8 a, vec_short8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_short8)(a), b)), 0) != 0xFF));
+}
+
+static inline int vec_any_ne(vec_short8 a, vec_bshort8 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_short8)(b))), 0) != 0xFF));
+}
+
+static inline int vec_any_ne(vec_uint4 a, vec_uint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF));
+}
+
+static inline int vec_any_ne(vec_int4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF));
+}
+
+static inline int vec_any_ne(vec_bint4 a, vec_int4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq((vec_int4)(a), b)), 0) != 0xF));
+}
+
+static inline int vec_any_ne(vec_int4 a, vec_bint4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, (vec_int4)(b))), 0) != 0xF));
+}
+
+static inline int vec_any_ne(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(a, b)), 0) != 0xF));
+}
+
+
+/* vec_any_nge (any elements not greater than or eqaul)
+ * ===========
+ */
+static inline int vec_any_nge(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_orx(spu_rlmask(spu_cmpgt(b, a), -31)), 0)));
+}
+
+/* vec_any_ngt (any elements not greater than)
+ * ===========
+ */
+static inline int vec_any_ngt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0xF));
+}
+
+
+/* vec_any_nle (any elements not less than or equal)
+ * ===========
+ */
+static inline int vec_any_nle(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(a, b)), 0) != 0));
+}
+
+
+/* vec_any_nlt (any elements not less than)
+ * ===========
+ */
+static inline int vec_any_nlt(vec_float4 a, vec_float4 b)
+{
+  return ((int)(spu_extract(spu_gather(spu_cmpgt(b, a)), 0) != 0xF));
+}
+
+
+/* vec_any_numeric (any elements numeric)
+ * ===============
+ */
+static inline int vec_any_numeric(vec_float4 a)
+{
+  vec_uint4 exp;
+
+  exp = spu_and(spu_rlmask((vec_uint4)(a), -23), 0xFF);
+  return ((int)(spu_extract(spu_gather(spu_cmpeq(exp, 255)), 0) != 0xF));
+}
+
+
+/* vec_any_out (any elements out of bounds)
+ * ===========
+ */
+static inline int vec_any_out(vec_float4 a, vec_float4 b)
+{
+  return (spu_extract(spu_gather(spu_nor(spu_cmpabsgt(a, b), (vec_uint4)(spu_rlmaska((vec_int4)(b), -31)))), 0) != 0xF);
+}
+
+#endif /* __SPU__ */
+#endif /* __cplusplus */
+#endif /* !_VMX2SPU_H_ */
index 5dc2136..46e8612 100644 (file)
@@ -822,6 +822,9 @@ for GNU/Linux.
 Andrey Slepuhin for assorted AIX hacking.
 
 @item
 Andrey Slepuhin for assorted AIX hacking.
 
 @item
+Trevor Smigiel for contributing the SPU port.
+
+@item
 Christopher Smith did the port for Convex machines.
 
 @item
 Christopher Smith did the port for Convex machines.
 
 @item
index 3576b71..fa7f31e 100644 (file)
@@ -2054,8 +2054,8 @@ defined by shared libraries.
 
 @item naked
 @cindex function without a prologue/epilogue code
 
 @item naked
 @cindex function without a prologue/epilogue code
-Use this attribute on the ARM, AVR, C4x and IP2K ports to indicate that the
-specified function does not need prologue/epilogue sequences generated by
+Use this attribute on the ARM, AVR, C4x, IP2K and SPU ports to indicate that
+the specified function does not need prologue/epilogue sequences generated by
 the compiler.  It is up to the programmer to provide these sequences.
 
 @item near
 the compiler.  It is up to the programmer to provide these sequences.
 
 @item near
@@ -3416,6 +3416,12 @@ documentation in the @xref{i386 Variable Attributes}, section.
 For documentation of @code{altivec} attribute please see the
 documentation in the @xref{PowerPC Type Attributes}, section.
 
 For documentation of @code{altivec} attribute please see the
 documentation in the @xref{PowerPC Type Attributes}, section.
 
+@subsection SPU Variable Attributes
+
+The SPU supports the @code{spu_vector} attribute for variables.  For
+documentation of this attribute please see the documentation in the
+@xref{SPU Type Attributes}, section.
+
 @subsection Xstormy16 Variable Attributes
 
 One attribute is currently defined for xstormy16 configurations:
 @subsection Xstormy16 Variable Attributes
 
 One attribute is currently defined for xstormy16 configurations:
@@ -3795,6 +3801,15 @@ __attribute__((altivec(bool__))) unsigned
 These attributes mainly are intended to support the @code{__vector},
 @code{__pixel}, and @code{__bool} AltiVec keywords.
 
 These attributes mainly are intended to support the @code{__vector},
 @code{__pixel}, and @code{__bool} AltiVec keywords.
 
+@anchor{SPU Type Attributes}
+@subsection SPU Type Attributes
+
+The SPU supports the @code{spu_vector} attribute for types.  This attribute
+allows one to declare vector data types supported by the Sony/Toshiba/IBM SPU
+Language Extensions Specification.  It is intended to support the
+@code{__vector} keyword.
+
+
 @node Inline
 @section An Inline Function is As Fast As a Macro
 @cindex inline functions
 @node Inline
 @section An Inline Function is As Fast As a Macro
 @cindex inline functions
@@ -6157,6 +6172,7 @@ instructions, but allow the compiler to schedule those calls.
 * MIPS Paired-Single Support::
 * PowerPC AltiVec Built-in Functions::
 * SPARC VIS Built-in Functions::
 * MIPS Paired-Single Support::
 * PowerPC AltiVec Built-in Functions::
 * SPARC VIS Built-in Functions::
+* SPU Built-in Functions::
 @end menu
 
 @node Alpha Built-in Functions
 @end menu
 
 @node Alpha Built-in Functions
@@ -9736,6 +9752,62 @@ v8qi __builtin_vis_fpmerge (v4qi, v4qi);
 int64_t __builtin_vis_pdist (v8qi, v8qi, int64_t);
 @end smallexample
 
 int64_t __builtin_vis_pdist (v8qi, v8qi, int64_t);
 @end smallexample
 
+@node SPU Built-in Functions
+@subsection SPU Built-in Functions
+
+GCC provides extensions for the SPU processor as described in the
+Sony/Toshiba/IBM SPU Language Extensions Specification, which can be
+found at @uref{http://cell.scei.co.jp/} or
+@uref{http://www.ibm.com/developerworks/power/cell/}.  GCC's
+implementation differs in several ways.
+
+@itemize @bullet
+
+@item
+The optional extension of specifying vector constants in parentheses is
+not supported.
+
+@item
+A vector initializer requires no cast if the vector constant is of the
+same type as the variable it is initializing.
+
+@item
+If @code{signed} or @code{unsigned} is omitted, the signedness of the
+vector type is the default signedness of the base type.  The default
+varies depending on the operating system, so a portable program should
+always specify the signedness.
+
+@item
+By default, the keyword @code{__vector} is added. The macro
+@code{vector} is defined in @code{<spu_intrinsics.h>} and can be
+undefined.
+
+@item
+GCC allows using a @code{typedef} name as the type specifier for a
+vector type.
+
+@item
+For C, overloaded functions are implemented with macros so the following
+does not work:
+
+@smallexample
+  spu_add ((vector signed int)@{1, 2, 3, 4@}, foo);
+@end smallexample
+
+Since @code{spu_add} is a macro, the vector constant in the example
+is treated as four separate arguments.  Wrap the entire argument in
+parentheses for this to work.
+
+@item
+The extended version of @code{__builtin_expect} is not supported.
+
+@end itemize
+
+@emph{Note:} Only the interface descibed in the aforementioned
+specification is supported. Internally, GCC uses built-in functions to
+implement the required functionality, but these are not supported and
+are subject to change without notice.
+
 @node Target Format Checks
 @section Format Checks Specific to Particular Target Machines
 
 @node Target Format Checks
 @section Format Checks Specific to Particular Target Machines
 
index f47cb62..3cd8219 100644 (file)
@@ -728,6 +728,12 @@ See RS/6000 and PowerPC Options.
 -mv8plus  -mno-v8plus  -mvis  -mno-vis
 -threads -pthreads -pthread}
 
 -mv8plus  -mno-v8plus  -mvis  -mno-vis
 -threads -pthreads -pthread}
 
+@emph{SPU Options}
+@gccoptlist{-mwarn-reloc -merror-reloc @gol
+-msafe-dma -munsafe-dma @gol
+-mbranch-hints @gol
+-msmall-mem -mlarge-mem}
+
 @emph{System V Options}
 @gccoptlist{-Qy  -Qn  -YP,@var{paths}  -Ym,@var{dir}}
 
 @emph{System V Options}
 @gccoptlist{-Qy  -Qn  -YP,@var{paths}  -Ym,@var{dir}}
 
@@ -7358,6 +7364,7 @@ platform.
 * Score Options::
 * SH Options::
 * SPARC Options::
 * Score Options::
 * SH Options::
 * SPARC Options::
+* SPU Options::
 * System V Options::
 * TMS320C3x/C4x Options::
 * V850 Options::
 * System V Options::
 * TMS320C3x/C4x Options::
 * V850 Options::
@@ -12781,6 +12788,57 @@ that of libraries supplied with it.
 This is a synonym for @option{-pthreads}.
 @end table
 
 This is a synonym for @option{-pthreads}.
 @end table
 
+@node SPU Options
+@subsection SPU Options
+@cindex SPU options
+
+These @samp{-m} options are supported on the SPU:
+
+@table @gcctabopt
+@item -mwarn-reloc
+@itemx -merror-reloc
+@opindex mwarn-reloc
+@opindex merror-reloc
+
+The loader for SPU does not handle dynamic relocations.  By default, GCC
+will give an error when it generates code that requires a dynamic
+relocation.  @option{-mno-error-reloc} disables the error,
+@option{-mwarn-reloc} will generate a warning instead.
+
+@item -msafe-dma
+@itemx -munsafe-dma
+@opindex msafe-dma
+@opindex munsafe-dma
+
+Instructions which initiate or test completion of DMA must not be
+reordered with respect to loads and stores of the memory which is being
+accessed.  Users typically address this problem using the volatile
+keyword, but that can lead to inefficient code in places where the
+memory is known to not change.  Rather than mark the memory as volatile
+we treat the DMA instructions as potentially effecting all memory.  With
+@option{-munsafe-dma} users must use the volatile keyword to protect
+memory accesses.
+
+@item -mbranch-hints
+@opindex mbranch-hints
+
+By default, GCC will generate a branch hint instruction to avoid
+pipeline stalls for always taken or probably taken branches.  A hint
+will not be generated closer than 8 instructions away from its branch.
+There is little reason to disable them, except for debugging purposes,
+or to make an object a little bit smaller.
+
+@item -msmall-mem
+@itemx -mlarge-mem
+@opindex msmall-mem
+@opindex mlarge-mem
+
+By default, GCC generates code assuming that addresses are never larger
+than 18 bits.  With @option{-mlarge-mem} code is generated that assumes
+a full 32 bit address.
+
+@end table
+
 @node System V Options
 @subsection Options for System V
 
 @node System V Options
 @subsection Options for System V
 
index 26be25c..2696eca 100644 (file)
@@ -2630,6 +2630,76 @@ Vector zero
 
 @end table
 
 
 @end table
 
+@item SPU---@file{config/spu/spu.h}
+@table @code
+@item a
+An immediate which can be loaded with the il/ila/ilh/ilhu instructions.  const_int is treated as a 64 bit value.  
+
+@item c
+An immediate for and/xor/or instructions.  const_int is treated as a 64 bit value.  
+
+@item d
+An immediate for the @code{iohl} instruction.  const_int is treated as a 64 bit value.  
+
+@item f
+An immediate which can be loaded with @code{fsmbi}.  
+
+@item A
+An immediate which can be loaded with the il/ila/ilh/ilhu instructions.  const_int is treated as a 32 bit value.  
+
+@item B
+An immediate for most arithmetic instructions.  const_int is treated as a 32 bit value.  
+
+@item C
+An immediate for and/xor/or instructions.  const_int is treated as a 32 bit value.  
+
+@item D
+An immediate for the @code{iohl} instruction.  const_int is treated as a 32 bit value.  
+
+@item I
+A constant in the range [-64, 63] for shift/rotate instructions.  
+
+@item J
+An unsigned 7-bit constant for conversion/nop/channel instructions.  
+
+@item K
+A signed 10-bit constant for most arithmetic instructions.  
+
+@item M
+A signed 16 bit immediate for @code{stop}.  
+
+@item N
+An unsigned 16-bit constant for @code{iohl} and @code{fsmbi}.  
+
+@item O
+An unsigned 7-bit constant whose 3 least significant bits are 0.  
+
+@item P
+An unsigned 3-bit constant for 16-byte rotates and shifts 
+
+@item R
+Call operand, reg, for indirect calls 
+
+@item S
+Call operand, symbol, for relative calls.  
+
+@item T
+Call operand, const_int, for absolute calls.  
+
+@item U
+An immediate which can be loaded with the il/ila/ilh/ilhu instructions.  const_int is sign extended to 128 bit.  
+
+@item W
+An immediate for shift and rotate instructions.  const_int is treated as a 32 bit value.  
+
+@item Y
+An immediate for and/xor/or instructions.  const_int is sign extended as a 128 bit.  
+
+@item Z
+An immediate for the @code{iohl} instruction.  const_int is sign extended to 128 bit.  
+
+@end table
+
 @item TMS320C3x/C4x---@file{config/c4x/c4x.h}
 @table @code
 @item a
 @item TMS320C3x/C4x---@file{config/c4x/c4x.h}
 @table @code
 @item a
index 8fd237d..59838ec 100644 (file)
@@ -1,3 +1,8 @@
+2006-11-20  Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
+
+       * configure.ac (need_64bit_hwint): Need 64bit hwint for SPU.
+       * configure : Rebuilt.
+
 2006-11-01     Douglas Gregor <doug.gregor@gmail.com>
 
        * include/cpplib.h (enum c_lang): Add CLK_GNUCXX0X and CLK_CXX0X
 2006-11-01     Douglas Gregor <doug.gregor@gmail.com>
 
        * include/cpplib.h (enum c_lang): Add CLK_GNUCXX0X and CLK_CXX0X
index 496f1fc..783cb7c 100755 (executable)
@@ -8244,6 +8244,7 @@ case $target in
        sparc64*-*-* | ultrasparc-*-freebsd* | \
        sparcv9-*-solaris2* | \
        sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
        sparc64*-*-* | ultrasparc-*-freebsd* | \
        sparcv9-*-solaris2* | \
        sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
+       spu-*-* | \
        sh[123456789l]*-*-*)
                need_64bit_hwint=yes ;;
        i[34567]86-*-linux*)
        sh[123456789l]*-*-*)
                need_64bit_hwint=yes ;;
        i[34567]86-*-linux*)
index 195d626..8a23633 100644 (file)
@@ -128,6 +128,7 @@ case $target in
        sparc64*-*-* | ultrasparc-*-freebsd* | \
        sparcv9-*-solaris2* | \
        sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
        sparc64*-*-* | ultrasparc-*-freebsd* | \
        sparcv9-*-solaris2* | \
        sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
+       spu-*-* | \
        sh[123456789l]*-*-*)
                need_64bit_hwint=yes ;;
        i[34567]86-*-linux*)
        sh[123456789l]*-*-*)
                need_64bit_hwint=yes ;;
        i[34567]86-*-linux*)