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>
 
+       * 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>
index c8b5968..175c280 100755 (executable)
--- a/configure
+++ b/configure
@@ -1598,6 +1598,9 @@ case "${target}" in
     ;;
   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}"
     ;;
index 1f5e3bd..3ae50e0 100644 (file)
@@ -774,6 +774,9 @@ case "${target}" in
     ;;
   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}"
     ;;
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
index 62f6212..ebabf9e 100644 (file)
@@ -321,6 +321,10 @@ sparc64*-*-*)
 sparc*-*-*)
        cpu_type=sparc
        ;;
+spu*-*-*)
+       cpu_type=spu
+       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"
        ;;
+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"
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")
+