summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Barbato <lu_zero@gentoo.org>2006-07-20 18:09:52 +0000
committerLuca Barbato <lu_zero@gentoo.org>2006-07-20 18:09:52 +0000
commit4d4d5b19a15f08061db280f9338eace51ebc304d (patch)
tree2b057e51c6c49260db471e2f664afcadb4dc9f81 /sys-devel
parentthe default scripts expect the images in the cell dir (diff)
downloadlu_zero-4d4d5b19a15f08061db280f9338eace51ebc304d.tar.gz
lu_zero-4d4d5b19a15f08061db280f9338eace51ebc304d.tar.bz2
lu_zero-4d4d5b19a15f08061db280f9338eace51ebc304d.zip
use CTARGET=spu for building spu binutils
svn path=/; revision=15
Diffstat (limited to 'sys-devel')
-rw-r--r--sys-devel/binutils/Manifest14
-rw-r--r--sys-devel/binutils/binutils-2.17-r1.ebuild25
-rw-r--r--sys-devel/binutils/files/binutils-2.17-cell.patch4735
-rw-r--r--sys-devel/binutils/files/digest-binutils-2.179
4 files changed, 4783 insertions, 0 deletions
diff --git a/sys-devel/binutils/Manifest b/sys-devel/binutils/Manifest
new file mode 100644
index 0000000..a7b84ca
--- /dev/null
+++ b/sys-devel/binutils/Manifest
@@ -0,0 +1,14 @@
+AUX binutils-2.17-cell.patch 174500 RMD160 28d3c9fd9cec05bc5025ce85c4dbcefca7efad5f SHA1 84750d5057235e23c5d1181730e32dbcfc3e8dde SHA256 07bb9bfb53a0d0dd257bd6599bb9ea2b8ecb41f4c1030a92189ef3f03f0d1f1b
+MD5 0c19e7049c42290b027142c57e0ef5aa files/binutils-2.17-cell.patch 174500
+RMD160 28d3c9fd9cec05bc5025ce85c4dbcefca7efad5f files/binutils-2.17-cell.patch 174500
+SHA256 07bb9bfb53a0d0dd257bd6599bb9ea2b8ecb41f4c1030a92189ef3f03f0d1f1b files/binutils-2.17-cell.patch 174500
+DIST binutils-2.17-patches-1.0.tar.bz2 8785 RMD160 326fcf5a278a7aa9027d16ec90b0fefa32c3e3b2 SHA1 71f8208a0947e9f296136857614ad98bee79720d SHA256 8d371229695e2c0d4045cffb15de1c43a9912245516029c59b2a606184711f11
+DIST binutils-2.17-uclibc-patches-1.0.tar.bz2 1569 RMD160 b48156b39bb84b1955ac66e8d0473e50e7780ea9 SHA1 05586b61395460e8479dda7a985f164572a44cc3 SHA256 9d63c8d2450f0ac8e164cf30c2e96b4fd9fe95356a9426526545445169c810c6
+DIST binutils-2.17.tar.bz2 13795751 RMD160 3995d7ed97f115e76ce55b4c1f5256d53559c84f SHA1 a557686eef68362ea31a3aa41ce274e3eeae1ef0 SHA256 e2c33ce6f23c9a366f109ced295626cb2f8bd6b2f08ff9df6dafb5448505a25e
+EBUILD binutils-2.17.ebuild 564 RMD160 e4241ac77c646437f34a7e509ea6da2d386e7251 SHA1 6f634c5384681fb0b52cc305c1d7c19adddb11b7 SHA256 0054bc5cdcbb46ffc54de0944cf7ad57fc292e1473d2f9844ff7429077cd06b8
+MD5 925f9abadd87a7ff2dae5e9b631f1cfa binutils-2.17.ebuild 564
+RMD160 e4241ac77c646437f34a7e509ea6da2d386e7251 binutils-2.17.ebuild 564
+SHA256 0054bc5cdcbb46ffc54de0944cf7ad57fc292e1473d2f9844ff7429077cd06b8 binutils-2.17.ebuild 564
+MD5 2e0e5585fe4c9d72757a716f4444f05a files/digest-binutils-2.17 819
+RMD160 f41271faede7f99bf83dd8d5b756dfd2e6803837 files/digest-binutils-2.17 819
+SHA256 2b8bbb39108c574f8005f86baedd271db495382db1d9ce61e63a0ad3a059c840 files/digest-binutils-2.17 819
diff --git a/sys-devel/binutils/binutils-2.17-r1.ebuild b/sys-devel/binutils/binutils-2.17-r1.ebuild
new file mode 100644
index 0000000..ec21de5
--- /dev/null
+++ b/sys-devel/binutils/binutils-2.17-r1.ebuild
@@ -0,0 +1,25 @@
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/sys-devel/binutils/binutils-2.17.ebuild,v 1.8 2006/07/05 22:54:04 vapier Exp $
+
+PATCHVER="1.0"
+UCLIBC_PATCHVER="1.0"
+ELF2FLT_VER=""
+inherit toolchain-binutils autotools
+
+# ARCH - packages to test before marking
+KEYWORDS="-* ~amd64 ~ppc ~ppc64 ~x86"
+
+src_unpack() {
+ mkdir ${WORKDIR}/patch
+ cp ${FILESDIR}/${P}-cell.patch \
+ ${WORKDIR}/patch/99_all_cbe_arch_update.patch
+ toolchain-binutils_src_unpack
+ cd ${S}
+ for dir in bfd gas ld opcodes
+ do
+ pushd ${dir}
+ eautoreconf
+ popd
+ done
+}
diff --git a/sys-devel/binutils/files/binutils-2.17-cell.patch b/sys-devel/binutils/files/binutils-2.17-cell.patch
new file mode 100644
index 0000000..cb241eb
--- /dev/null
+++ b/sys-devel/binutils/files/binutils-2.17-cell.patch
@@ -0,0 +1,4735 @@
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/Makefile.am binutils/bfd/Makefile.am
+--- binutils-2.16.1/bfd/Makefile.am 2005-06-12 20:58:52.000000000 +0200
++++ binutils/bfd/Makefile.am 2006-03-30 01:23:21.000000000 +0200
+@@ -58,6 +58,7 @@
+ cpu-s390.lo \
+ cpu-sh.lo \
+ cpu-sparc.lo \
++ cpu-spu.lo \
+ cpu-tic30.lo \
+ cpu-tic4x.lo \
+ cpu-tic54x.lo \
+@@ -116,6 +117,7 @@
+ cpu-s390.c \
+ cpu-sh.c \
+ cpu-sparc.c \
++ cpu-spu.c \
+ cpu-tic30.c \
+ cpu-tic4x.c \
+ cpu-tic54x.c \
+@@ -262,6 +264,7 @@
+ elf32-sh64.lo \
+ elf32-sh64-com.lo \
+ elf32-sparc.lo \
++ elf32-spu.lo \
+ elf32-v850.lo \
+ elf32-vax.lo \
+ elf32-xstormy16.lo \
+@@ -430,6 +433,7 @@
+ elf32-sh64-com.c \
+ elfxx-sparc.c \
+ elf32-sparc.c \
++ elf32-spu.c \
+ elf32-v850.c \
+ elf32-vax.c \
+ elf32-xstormy16.c \
+@@ -944,6 +948,7 @@
+ cpu-sh.lo: cpu-sh.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
+ $(srcdir)/../opcodes/sh-opc.h
+ cpu-sparc.lo: cpu-sparc.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
++cpu-spu.lo: cpu-spu.c $(INCDIR)/filenames.h
+ cpu-tic30.lo: cpu-tic30.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+ cpu-tic4x.lo: cpu-tic4x.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+ cpu-tic54x.lo: cpu-tic54x.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
+@@ -1336,6 +1341,10 @@
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/sparc.h \
+ $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/sparc.h \
+ elfxx-sparc.h elf32-target.h elf-vxworks.h
++elf32-spu.lo: elf32-spu.c $(INCDIR)/filenames.h elf-bfd.h bfd.h \
++ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
++ $(INCDIR)/bfdlink.h $(INCDIR)/elf/spu.h $(INCDIR)/elf/reloc-macros.h \
++ elf32-target.h
+ elf32-v850.lo: elf32-v850.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
+ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/v850.h \
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/archures.c binutils/bfd/archures.c
+--- binutils-2.16.1/bfd/archures.c 2005-01-17 15:08:03.000000000 +0100
++++ binutils/bfd/archures.c 2006-03-30 01:23:21.000000000 +0200
+@@ -204,11 +204,14 @@
+ .#define bfd_mach_ppc_rs64iii 643
+ .#define bfd_mach_ppc_7400 7400
+ .#define bfd_mach_ppc_e500 500
++.#define bfd_mach_cell_ppu 501
+ . bfd_arch_rs6000, {* IBM RS/6000 *}
+ .#define bfd_mach_rs6k 6000
+ .#define bfd_mach_rs6k_rs1 6001
+ .#define bfd_mach_rs6k_rsc 6003
+ .#define bfd_mach_rs6k_rs2 6002
++. bfd_arch_spu, {* PowerPC SPU *}
++.#define bfd_mach_spu 256
+ . bfd_arch_hppa, {* HP PA RISC *}
+ .#define bfd_mach_hppa10 10
+ .#define bfd_mach_hppa11 11
+@@ -442,6 +445,7 @@
+ extern const bfd_arch_info_type bfd_s390_arch;
+ extern const bfd_arch_info_type bfd_sh_arch;
+ extern const bfd_arch_info_type bfd_sparc_arch;
++extern const bfd_arch_info_type bfd_spu_arch;
+ extern const bfd_arch_info_type bfd_tic30_arch;
+ extern const bfd_arch_info_type bfd_tic4x_arch;
+ extern const bfd_arch_info_type bfd_tic54x_arch;
+@@ -503,6 +507,7 @@
+ &bfd_s390_arch,
+ &bfd_sh_arch,
+ &bfd_sparc_arch,
++ &bfd_spu_arch,
+ &bfd_tic30_arch,
+ &bfd_tic4x_arch,
+ &bfd_tic54x_arch,
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/bfd-in2.h binutils/bfd/bfd-in2.h
+--- binutils-2.16.1/bfd/bfd-in2.h 2005-03-02 22:23:20.000000000 +0100
++++ binutils/bfd/bfd-in2.h 2006-03-30 01:23:21.000000000 +0200
+@@ -921,6 +921,8 @@
+ bfd_boolean bfd_fill_in_gnu_debuglink_section
+ (bfd *abfd, struct bfd_section *sect, const char *filename);
+
++void bfd_set_direction(bfd *abfd, int fdflags);
++
+ /* Extracted from libbfd.c. */
+
+ /* Byte swapping macros for user section data. */
+@@ -1649,11 +1651,15 @@
+ #define bfd_mach_ppc_rs64iii 643
+ #define bfd_mach_ppc_7400 7400
+ #define bfd_mach_ppc_e500 500
++#define bfd_mach_cell_ppu 501
++#define bfd_mach_cell_ppu_mambo 502
+ bfd_arch_rs6000, /* IBM RS/6000 */
+ #define bfd_mach_rs6k 6000
+ #define bfd_mach_rs6k_rs1 6001
+ #define bfd_mach_rs6k_rsc 6003
+ #define bfd_mach_rs6k_rs2 6002
++ bfd_arch_spu, /* PowerPC SPU */
++#define bfd_mach_spu 256
+ bfd_arch_hppa, /* HP PA RISC */
+ #define bfd_mach_hppa10 10
+ #define bfd_mach_hppa11 11
+@@ -3638,6 +3644,20 @@
+ BFD_RELOC_860_HIGOT,
+ BFD_RELOC_860_HIGOTOFF,
+
++/* SPU Relocations. */
++ BFD_RELOC_SPU_IMM7,
++ BFD_RELOC_SPU_IMM8,
++ BFD_RELOC_SPU_IMM10,
++ BFD_RELOC_SPU_IMM10W,
++ BFD_RELOC_SPU_IMM16,
++ BFD_RELOC_SPU_IMM16W,
++ BFD_RELOC_SPU_IMM18,
++ BFD_RELOC_SPU_PCREL9a,
++ BFD_RELOC_SPU_PCREL9b,
++ BFD_RELOC_SPU_PCREL16,
++ BFD_RELOC_SPU_LO16,
++ BFD_RELOC_SPU_HI16,
++
+ /* OpenRISC Relocations. */
+ BFD_RELOC_OPENRISC_ABS_26,
+ BFD_RELOC_OPENRISC_REL_26,
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/config.bfd binutils/bfd/config.bfd
+--- binutils-2.16.1/bfd/config.bfd 2005-01-31 18:18:47.000000000 +0100
++++ binutils/bfd/config.bfd 2006-03-30 01:23:21.000000000 +0200
+@@ -77,10 +77,12 @@
+ pdp11*) targ_archs=bfd_pdp11_arch ;;
+ pj*) targ_archs="bfd_pj_arch bfd_i386_arch";;
+ powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
++ppu*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
+ rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
+ s390*) targ_archs=bfd_s390_arch ;;
+ sh*) targ_archs=bfd_sh_arch ;;
+ sparc*) targ_archs=bfd_sparc_arch ;;
++spu*) targ_archs=bfd_spu_arch ;;
+ strongarm*) targ_archs=bfd_arm_arch ;;
+ thumb*) targ_archs=bfd_arm_arch ;;
+ v850*) targ_archs=bfd_v850_arch ;;
+@@ -1053,6 +1055,12 @@
+ targ_selvecs="bfd_powerpcle_pei_vec bfd_powerpc_pei_vec bfd_powerpcle_pe_vec bfd_powerpc_pe_vec"
+ ;;
+
++ ppu-*-lv2)
++ targ_defvec=bfd_elf64_powerpc_vec
++ targ_selvecs="bfd_elf32_spu_vec"
++ want64=true
++ ;;
++
+ s390-*-linux*)
+ targ_defvec=bfd_elf32_s390_vec
+ targ64_selvecs=bfd_elf64_s390_vec
+@@ -1286,6 +1294,16 @@
+ targ_underscore=yes
+ ;;
+
++ spu-*-lv2)
++ targ_defvec=bfd_elf32_spu_vec
++ targ_selvecs="bfd_elf64_powerpc_vec"
++ ;;
++
++ spu-*-elf)
++ targ_defvec=bfd_elf32_spu_vec
++ targ_selvecs="bfd_elf32_powerpc_vec bfd_elf64_powerpc_vec"
++ ;;
++
+ #if HAVE_host_aout_vec
+ tahoe-*-*)
+ targ_defvec=host_aout_vec
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/configure.in binutils/bfd/configure.in
+--- binutils-2.16.1/bfd/configure.in 2005-06-12 20:58:40.000000000 +0200
++++ binutils/bfd/configure.in 2006-03-30 01:23:21.000000000 +0200
+@@ -659,6 +659,7 @@
+ bfd_elf32_shlnbsd_vec) tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ bfd_elf32_shnbsd_vec) tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ bfd_elf32_sparc_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
++ bfd_elf32_spu_vec) tb="$tb elf32-spu.lo elf32.lo $elf" ;;
+ bfd_elf32_sparc_vxworks_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ bfd_elf32_tradbigmips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ bfd_elf32_tradlittlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/cpu-powerpc.c binutils/bfd/cpu-powerpc.c
+--- binutils-2.16.1/bfd/cpu-powerpc.c 2005-03-03 12:40:58.000000000 +0100
++++ binutils/bfd/cpu-powerpc.c 2006-03-30 01:23:21.000000000 +0200
+@@ -295,6 +295,34 @@
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+- 0
++ &bfd_powerpc_archs[15],
++ },
++ {
++ 64, /* 64 bits in a word */
++ 64, /* 64 bits in an address */
++ 8, /* 8 bits in a byte */
++ bfd_arch_powerpc,
++ bfd_mach_cell_ppu,
++ "powerpc",
++ "Cell:PPU",
++ 3,
++ FALSE,
++ powerpc_compatible,
++ bfd_default_scan,
++ &bfd_powerpc_archs[16],
++ },
++ {
++ 64, /* 64 bits in a word */
++ 64, /* 64 bits in an address */
++ 8, /* 8 bits in a byte */
++ bfd_arch_powerpc,
++ bfd_mach_cell_ppu_mambo,
++ "powerpc",
++ "Cell:Mambo",
++ 3,
++ FALSE,
++ powerpc_compatible,
++ bfd_default_scan,
++ 0 /* pointer to next bfd_arch_info_type objenct */
+ }
+ };
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/cpu-spu.c binutils/bfd/cpu-spu.c
+--- binutils-2.16.1/bfd/cpu-spu.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils/bfd/cpu-spu.c 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,63 @@
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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 "bfd.h"
++#include "sysdep.h"
++#include "libbfd.h"
++
++
++static const bfd_arch_info_type *spu_compatible
++ PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
++
++static const bfd_arch_info_type *
++spu_compatible (a,b)
++ const bfd_arch_info_type *a;
++ const bfd_arch_info_type *b;
++{
++ BFD_ASSERT (a->arch == bfd_arch_spu);
++ switch (b->arch)
++ {
++ default:
++ return NULL;
++ case bfd_arch_spu:
++ return bfd_default_compatible (a, b);
++ }
++ /*NOTREACHED*/
++}
++
++const bfd_arch_info_type bfd_spu_arch[] =
++{
++ {
++ 32, /* 32 bits in a word */
++ 32, /* 32 bits in an address */
++ 8, /* 8 bits in a byte */
++ bfd_arch_spu, /* architecture */
++ bfd_mach_spu, /* machine */
++ "spu", /* architecture name */
++ "spu:256K", /* printable name */
++ 3, /* aligned power */
++ TRUE, /* the default machine for the architecture */
++ spu_compatible, /* the spu is only compatible with itself, see above */
++ bfd_default_scan,
++ 0, /* next -- there are none! */
++ }
++};
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/elf.c binutils/bfd/elf.c
+--- binutils-2.16.1/bfd/elf.c 2005-05-30 00:00:10.000000000 +0200
++++ binutils/bfd/elf.c 2006-03-30 01:23:21.000000000 +0200
+@@ -41,6 +41,10 @@
+ #include "elf-bfd.h"
+ #include "libiberty.h"
+
++#if (defined(BPA))
++#include "elf/spu.h"
++#endif
++
+ static int elf_sort_sections (const void *, const void *);
+ static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
+ static bfd_boolean prep_headers (bfd *);
+@@ -3400,6 +3404,10 @@
+ asection *dynsec, *eh_frame_hdr;
+ bfd_size_type amt;
+
++#if defined(BPA)
++ bfd_boolean toe_segment=FALSE;
++#endif
++
+ if (elf_tdata (abfd)->segment_map != NULL)
+ return TRUE;
+
+@@ -3511,6 +3519,19 @@
+ one (we build the last one after this loop). */
+ new_segment = FALSE;
+ }
++#if defined(BPA)
++ else if (strcmp (hdr->name, ".toe") == 0)
++ {
++ new_segment = TRUE;
++ toe_segment = TRUE;
++ }
++ else if (toe_segment == TRUE)
++ {
++ /* no longer in toe_segment */
++ new_segment = TRUE;
++ toe_segment = FALSE;
++ }
++#endif
+ else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
+ {
+ /* If this section has a different relation between the
+@@ -3964,7 +3985,11 @@
+ bfd_size_type align;
+ bfd_vma adjust;
+
+- if ((abfd->flags & D_PAGED) != 0 && bed->maxpagesize > align)
++ /* CELL LOCAL Begin */
++ /* FIXME - need to double check this merge */
++ if ((abfd->flags & D_PAGED) != 0 && bed->maxpagesize > align
++ || m == elf_tdata (abfd)->segment_map)
++ /* CELL LOCAL End */
+ align = bed->maxpagesize;
+ else
+ {
+@@ -4263,7 +4288,152 @@
+ p->p_flags |= PF_W;
+ }
+ }
++
++#if (defined(BPA))
++ if ((bfd_get_arch(abfd) == bfd_arch_spu)) {
++#define SPU_SEG_ALIGN 0x10
++ if( p->p_type == PT_LOAD ) {
++ bfd_vma adjust_segment;
++ bfd_vma adjust_memsz;
++ /* segment file size is increased to multiple of SPU_SEG_ALIGN byte for DMA transfer. */
++ adjust_segment = p->p_filesz % SPU_SEG_ALIGN ;
++ if ( adjust_segment != 0 ) {
++ p->p_filesz += (SPU_SEG_ALIGN - adjust_segment);
++ off += (SPU_SEG_ALIGN - adjust_segment) ;
++ voff += (SPU_SEG_ALIGN - adjust_segment) ;
++ }
++ /* The memory size of the segment is aligned to 16byte boundary.*/
++ adjust_memsz = p->p_memsz % SPU_SEG_ALIGN ;
++ if ( adjust_memsz != 0)
++ p->p_memsz += (SPU_SEG_ALIGN - adjust_memsz);
++ }
++ }
++#endif
++
++ }
++
++
++#if (defined(BPA))
++
++ /* Offset for PT_NOTE segment contains SPU_PTNOTE_SPUNAME section is set in this routine.
++
++ In actual assign_file_positions_for_segments() doesn't gurantee to set file offset
++ in program header for non PT_LOAD segment.
++
++ In detail, procedure are below.
++ 1) offset is set for sections in PT_LOAD segments. (in assign_file_positions_for_segments())
++ 2) program headers are created and written. (in assign_file_positions_for_segments())
++ 3) offset is set for sections in non PT_LOAD segments. (in assign_file_positions_except_relocs())
++
++ Note:
++ For example, file offset of PT_NOTE are set in normal system.
++ Because .note is contained in both PT_LOAD and PT_NOTE,
++ its offset are set in 1) and no problem occured.
++
++ So this routine is added to gurantee to set offset for SPU_PTNOTE_SPUNAME only contained in PT_NOTE.
++ */
++
++ {
++ unsigned int i;
++ Elf_Internal_Shdr **hdrpp;
++ Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
++ unsigned int num_sec = elf_numsections (abfd);
++ Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
++
++ if (bfd_get_arch(abfd) == bfd_arch_spu) {
++ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) {
++ Elf_Internal_Shdr *hdr;
++
++ hdr = *hdrpp;
++ if (hdr->bfd_section != NULL
++ && hdr->bfd_section->name != NULL
++ && (strcmp(hdr->bfd_section->name, SPU_PTNOTE_SPUNAME) == 0 )) {
++
++ off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
++
++ elf_tdata (abfd)->next_file_pos = off;
++ }
++ }
++ }
++ }
++#endif /* BPA */
++
++
++/* This is for SPU dynamic loading initial step. */
++#if 0
++#if (defined(BPA))
++ /* Offset for non PT_LOAD segments is set in this routine.
++ This added routine is exactly same in assign_file_positions_except_relocs().
++
++ In actual assign_file_positions_for_segments() doesn't gurantee to set file offset
++ in program header for non PT_LOAD segment.
++
++ In detail, procedure are below.
++ 1) offset is set for sections in PT_LOAD segments. (in assign_file_positions_for_segments())
++ 2) program headers are created and written. (in assign_file_positions_for_segments())
++ 3) offset is set for sections in non PT_LOAD segments. (in assign_file_positions_except_relocs())
++
++ So this routine is added to gurantee to set offset for not PT_LOAD segments.
++
++ Note:
++ For example, file offset of PT_DYNAMIC are set in normal system.
++ Because .dynamic are contained in both PT_LOAD and PT_DYNAMIC.
++ So its offset are set in 1) and no problem occured. */
++
++ {
++ unsigned int i;
++ Elf_Internal_Shdr **hdrpp;
++ Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
++ unsigned int num_sec = elf_numsections (abfd);
++ struct elf_obj_tdata * const tdata = elf_tdata (abfd);
++ Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
++
++ if ((bfd_get_arch(abfd) == bfd_arch_spu) && (i_ehdrp->e_type == ET_DYN)) {
++ /* Assign file positions for the other sections. */
++
++ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
++ {
++ Elf_Internal_Shdr *hdr;
++
++ hdr = *hdrpp;
++ if (hdr->bfd_section != NULL
++ && hdr->bfd_section->filepos != 0)
++ hdr->sh_offset = hdr->bfd_section->filepos;
++ else if ((hdr->sh_flags & SHF_ALLOC) != 0)
++ {
++ ((*_bfd_error_handler)
++ (_("%s: warning: allocated section `%s' not in segment"),
++ bfd_get_filename (abfd),
++ (hdr->bfd_section == NULL
++ ? "*unknown*"
++ : hdr->bfd_section->name)));
++ if ((abfd->flags & D_PAGED) != 0)
++ off += (hdr->sh_addr - off) % bed->maxpagesize;
++ else
++ off += (hdr->sh_addr - off) % hdr->sh_addralign;
++ off = _bfd_elf_assign_file_position_for_section (hdr, off,
++ false);
++ }
++ else if (hdr->sh_type == SHT_REL
++ || hdr->sh_type == SHT_RELA
++ || hdr == i_shdrpp[tdata->symtab_section]
++ || hdr == i_shdrpp[tdata->symtab_shndx_section]
++ || hdr == i_shdrpp[tdata->strtab_section])
++ hdr->sh_offset = -1;
++ else
++ off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
++
++ if (i == SHN_LORESERVE - 1)
++ {
++ i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
++ hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
++ }
++ }
++ }
++ elf_tdata (abfd)->next_file_pos = off;
+ }
++#endif
++#endif
+
+ /* Now that we have set the section file positions, we can set up
+ the file positions for the non PT_LOAD segments. */
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/elf32-spu.c binutils/bfd/elf32-spu.c
+--- binutils-2.16.1/bfd/elf32-spu.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils/bfd/elf32-spu.c 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,1015 @@
++/* SPU specific support for 32-bit ELF */
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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 "bfd.h"
++#include "sysdep.h"
++#include "bfdlink.h"
++#include "libbfd.h"
++#include "elf-bfd.h"
++#include "elf/spu.h"
++
++void spu_elf_info_to_howto PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
++void spu_elf_info_to_howto_rel PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
++reloc_howto_type *spu_elf_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type));
++static void spu_elf_final_write_processing PARAMS ((bfd *, bfd_boolean));
++static bfd_boolean spu_elf_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *,
++ asection *, bfd_byte *, Elf_Internal_Rela *,
++ Elf_Internal_Sym *, asection **));
++static asection * spu_elf_gc_mark_hook PARAMS ((asection *, struct bfd_link_info *,
++ Elf_Internal_Rela *, struct elf_link_hash_entry *,
++ Elf_Internal_Sym *));
++static bfd_boolean spu_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *,
++ const Elf_Internal_Rela *));
++
++#if defined(BPA)
++static void spu_elf_post_process_headers PARAMS ((bfd *, struct bfd_link_info *));
++static bfd_boolean spu_elf_section_processing PARAMS ((bfd *, Elf_Internal_Shdr *));
++static bfd_boolean spu_elf_always_size_sections PARAMS ((bfd *, struct bfd_link_info *));
++#endif
++
++/* When USE_REL is not defined bfd uses reloc entry addends
++ * instead of inserting the addend into the instruction.
++ * #define USE_REL 0
++ */
++
++
++/* Values of type 'enum elf_spu_reloc_type' are used to index this
++ * array, so it must be declared in the order of that type. */
++static reloc_howto_type elf_howto_table[] = {
++ HOWTO(R_SPU_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont, bfd_elf_generic_reloc, "SPU_NONE", FALSE, 0x00000000, 0x00000000, FALSE),
++ HOWTO(R_SPU_ADDR10, 4, 2,10, FALSE, 14, complain_overflow_bitfield, bfd_elf_generic_reloc, "SPU_ADDR10", FALSE, 0x00ffc000, 0x00ffc000, FALSE),
++ HOWTO(R_SPU_ADDR16, 2, 2,16, FALSE, 7, complain_overflow_bitfield, bfd_elf_generic_reloc, "SPU_ADDR16", FALSE, 0x007fff80, 0x007fff80, FALSE),
++ HOWTO(R_SPU_ADDR16_HI,16,2,16, FALSE, 7, complain_overflow_bitfield, bfd_elf_generic_reloc, "SPU_ADDR16_HI", FALSE, 0x007fff80, 0x007fff80, FALSE),
++ HOWTO(R_SPU_ADDR16_LO,0, 2,16, FALSE, 7, complain_overflow_dont, bfd_elf_generic_reloc, "SPU_ADDR16_LO", FALSE, 0x007fff80, 0x007fff80, FALSE),
++ HOWTO(R_SPU_ADDR18, 0, 2,18, FALSE, 7, complain_overflow_bitfield, bfd_elf_generic_reloc, "SPU_ADDR18", FALSE, 0x01ffff80, 0x01ffff80, FALSE),
++ HOWTO(R_SPU_GLOB_DAT, 0, 2,32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "SPU_GLOB_DAT", FALSE, 0xffffffff, 0xffffffff, FALSE),
++ HOWTO(R_SPU_REL16, 2, 2,16, TRUE, 7, complain_overflow_bitfield, bfd_elf_generic_reloc, "SPU_REL16", FALSE, 0x007fff80, 0x007fff80, TRUE),
++ HOWTO(R_SPU_ADDR7, 0, 2, 7, FALSE, 14, complain_overflow_dont, bfd_elf_generic_reloc, "SPU_ADDR7", FALSE, 0x001fc000, 0x001fc000, FALSE),
++ HOWTO(R_SPU_REL9, 2, 2, 9, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "SPU_REL9", FALSE, 0x0180007f, 0x0180007f, TRUE),
++ HOWTO(R_SPU_REL9I, 2, 2, 9, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "SPU_REL9I", FALSE, 0x0000c07f, 0x0000c07f, TRUE),
++ HOWTO(R_SPU_ADDR10I, 0, 2,10, FALSE, 14, complain_overflow_signed, bfd_elf_generic_reloc, "SPU_ADDR10I", FALSE, 0x00ffc000, 0x00ffc000, FALSE),
++ HOWTO(R_SPU_ADDR16I, 0, 2,16, FALSE, 7, complain_overflow_signed, bfd_elf_generic_reloc, "SPU_ADDR16I", FALSE, 0x007fff80, 0x007fff80, FALSE),
++};
++
++static struct bfd_elf_special_section const spu_elf_special_sections[]=
++{
++ { ".toe", 4, 0, SHT_PROGBITS, SHF_ALLOC },
++ { NULL, 0, 0, 0, 0 }
++};
++
++static enum elf_spu_reloc_type
++spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code)
++{
++ switch (code)
++ {
++ default:
++ return R_SPU_NONE;
++ case BFD_RELOC_SPU_IMM10W:
++ return R_SPU_ADDR10;
++ case BFD_RELOC_SPU_IMM16W:
++ return R_SPU_ADDR16;
++ case BFD_RELOC_SPU_LO16:
++ return R_SPU_ADDR16_LO;
++ case BFD_RELOC_SPU_HI16:
++ return R_SPU_ADDR16_HI;
++ case BFD_RELOC_SPU_IMM18:
++ return R_SPU_ADDR18;
++ case BFD_RELOC_32:
++ return R_SPU_GLOB_DAT;
++ case BFD_RELOC_SPU_PCREL16:
++ return R_SPU_REL16;
++ case BFD_RELOC_SPU_IMM7:
++ return R_SPU_ADDR7;
++ case BFD_RELOC_SPU_IMM8:
++ return R_SPU_NONE;
++ case BFD_RELOC_SPU_PCREL9a:
++ return R_SPU_REL9;
++ case BFD_RELOC_SPU_PCREL9b:
++ return R_SPU_REL9I;
++ case BFD_RELOC_SPU_IMM10:
++ return R_SPU_ADDR10I;
++ case BFD_RELOC_SPU_IMM16:
++ return R_SPU_ADDR16I;
++ }
++}
++
++void
++spu_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
++ arelent * cache_ptr ATTRIBUTE_UNUSED,
++ Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)
++{
++ enum elf_spu_reloc_type r_type;
++
++ r_type = (enum elf_spu_reloc_type) ELF32_R_TYPE (dst->r_info);
++ BFD_ASSERT (r_type < R_SPU_max);
++ cache_ptr->howto = &elf_howto_table[(int) r_type];
++}
++
++void
++spu_elf_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
++ arelent * cache_ptr, Elf_Internal_Rela * dst)
++{
++ enum elf_spu_reloc_type type;
++
++ type = (enum elf_spu_reloc_type) ELF32_R_TYPE (dst->r_info);
++ BFD_ASSERT (type < R_SPU_max);
++ cache_ptr->howto = &elf_howto_table[(int) type];
++}
++
++reloc_howto_type *
++spu_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
++ bfd_reloc_code_real_type code)
++{
++ return elf_howto_table + spu_elf_bfd_to_reloc_type (code);
++}
++
++/* Look through the relocs for a section during the first phase and
++ make any required dynamic sections.
++
++ We iterate over the relocations three times:
++
++ spu_elf_check_relocs
++ This creates any needed dynamic sections as we first read all the
++ input objects. We need to do create the sections now so they get
++ mapped to the correct output sections. At this points we don't
++ know which symbols are resolved from dynamic objects.
++
++ allocate_dynrelocs
++ This computes sizes of the sections. Now we do know which
++ symbols come from where, so we can determine the correct amount
++ of space to allocate. Some sections will require no space and
++ are stripped by spu_elf_size_dynamic_sections.
++
++ spu_elf_relocate_section
++ This finally creates the relocations in the correct section.
++ */
++static bfd_boolean
++spu_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
++ asection *sec, const Elf_Internal_Rela *relocs)
++{
++ Elf_Internal_Shdr *symtab_hdr;
++ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
++ const Elf_Internal_Rela *rel;
++ const Elf_Internal_Rela *rel_end;
++ asection *sreloc;
++ bfd *dynobj;
++
++ if (info->relocatable)
++ return TRUE;
++
++ /* Don't do anything special with non-loaded, non-alloced sections.
++ In particular, there's not much point in propagating relocs to
++ shared libs that the dynamic linker won't relocate. */
++ if ((sec->flags & SEC_ALLOC) == 0)
++ return TRUE;
++
++ dynobj = elf_hash_table (info)->dynobj;
++
++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
++
++ sym_hashes = elf_sym_hashes (abfd);
++ sym_hashes_end = (sym_hashes
++ + symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
++ - symtab_hdr->sh_info);
++
++ sreloc = NULL;
++
++ rel_end = relocs + sec->reloc_count;
++ for (rel = relocs; rel < rel_end; rel++)
++ {
++ unsigned long r_symndx;
++ struct elf_link_hash_entry *h;
++ enum elf_spu_reloc_type r_type;
++
++ r_symndx = ELF32_R_SYM (rel->r_info);
++ if (r_symndx < symtab_hdr->sh_info)
++ h = NULL;
++ else
++ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
++
++ r_type = ELF32_R_TYPE (rel->r_info);
++ switch (r_type)
++ {
++ case R_SPU_ADDR10:
++ case R_SPU_ADDR16:
++ case R_SPU_ADDR16_HI:
++ case R_SPU_ADDR16_LO:
++ case R_SPU_ADDR18:
++ case R_SPU_GLOB_DAT:
++ case R_SPU_REL16:
++ case R_SPU_ADDR7:
++ case R_SPU_ADDR10I:
++ case R_SPU_ADDR16I:
++ if (h != NULL
++ && (!h->def_regular
++ || h->root.type == bfd_link_hash_defweak
++ || (info->shared && ! info->symbolic)))
++ {
++ /* We might need to copy these reloc types into the output file.
++ Create a reloc section in dynobj. */
++ if (sreloc == NULL)
++ {
++ const char *name;
++
++ name = (bfd_elf_string_from_elf_section
++ (abfd,
++ elf_elfheader (abfd)->e_shstrndx,
++ elf_section_data (sec)->rel_hdr.sh_name));
++ if (name == NULL)
++ return FALSE;
++
++ if (strncmp (name, ".rela", 5) != 0
++ || strcmp (bfd_get_section_name (abfd, sec),
++ name + 5) != 0)
++ {
++ (*_bfd_error_handler)
++ (_("%B: bad relocation section name `%s\'"),
++ abfd, name);
++ bfd_set_error (bfd_error_bad_value);
++ }
++
++ if (dynobj == NULL)
++ dynobj = elf_hash_table (info)->dynobj = abfd;
++
++ sreloc = bfd_get_section_by_name (dynobj, name);
++ if (sreloc == NULL)
++ {
++ flagword flags;
++
++ sreloc = bfd_make_section (dynobj, name);
++ flags = (SEC_HAS_CONTENTS | SEC_READONLY
++ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
++ if ((sec->flags & SEC_ALLOC) != 0)
++ flags |= SEC_ALLOC | SEC_LOAD;
++ if (sreloc == NULL
++ || ! bfd_set_section_flags (dynobj, sreloc, flags)
++ || ! bfd_set_section_alignment (dynobj, sreloc, 3))
++ return FALSE;
++ }
++ elf_section_data (sec)->sreloc = sreloc;
++ }
++ }
++ break;
++
++ default:
++ break;
++ }
++ }
++ return TRUE;
++}
++
++
++static bfd_boolean
++spu_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
++ struct bfd_link_info *info,
++ bfd * input_bfd,
++ asection * input_section,
++ bfd_byte * contents,
++ Elf_Internal_Rela * relocs,
++ Elf_Internal_Sym * local_syms,
++ asection ** local_sections)
++{
++ Elf_Internal_Shdr *symtab_hdr;
++ struct elf_link_hash_entry **sym_hashes;
++ Elf_Internal_Rela *rel, *relend;
++ bfd_boolean ret = TRUE;
++
++ if (info->relocatable)
++ return TRUE;
++
++ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
++ sym_hashes = (struct elf_link_hash_entry **) (elf_sym_hashes (input_bfd));
++
++ rel = relocs;
++ relend = relocs + input_section->reloc_count;
++ for (; rel < relend; rel++)
++ {
++ int r_type;
++ reloc_howto_type *howto;
++ unsigned long r_symndx;
++ Elf_Internal_Sym *sym;
++ asection *sec;
++ struct elf_link_hash_entry *h;
++ const char *sym_name;
++ bfd_vma relocation;
++ bfd_reloc_status_type r;
++ bfd_boolean unresolved_reloc;
++ bfd_boolean warned;
++
++ r_symndx = ELF32_R_SYM (rel->r_info);
++ r_type = ELF32_R_TYPE (rel->r_info);
++ howto = elf_howto_table + r_type;
++ unresolved_reloc = FALSE;
++ warned = FALSE;
++
++ h = NULL;
++ sym = NULL;
++ sec = NULL;
++ if (r_symndx < symtab_hdr->sh_info)
++ {
++ sym = local_syms + r_symndx;
++ sec = local_sections[r_symndx];
++ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, NULL);
++ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
++ }
++ else
++ {
++ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
++ r_symndx, symtab_hdr, sym_hashes,
++ h, sec, relocation,
++ unresolved_reloc, warned);
++ sym_name = h->root.root.string;
++ }
++
++ switch (r_type)
++ {
++ /* Relocations that always need to be propagated if this is a shared
++ object. */
++ case R_SPU_ADDR10:
++ case R_SPU_ADDR16:
++ case R_SPU_ADDR16_HI:
++ case R_SPU_ADDR16_LO:
++ case R_SPU_ADDR18:
++ case R_SPU_GLOB_DAT:
++ case R_SPU_REL16:
++ case R_SPU_ADDR7:
++ case R_SPU_ADDR10I:
++ case R_SPU_ADDR16I:
++ /* r_symndx will be zero only for relocs against symbols
++ from removed linkonce sections, or sections discarded by
++ a linker script. */
++ if (r_symndx == 0)
++ break;
++ /* Fall thru. */
++
++ if ((info->shared
++ && (h == NULL
++ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
++ || h->root.type != bfd_link_hash_undefweak)
++ && (!SYMBOL_CALLS_LOCAL (info, h)))
++ || (!info->shared
++ && h != NULL
++ && h->dynindx != -1
++ && h->def_dynamic
++ && !h->def_regular))
++ {
++ Elf_Internal_Rela outrel;
++ bfd_boolean skip, relocate;
++ asection *sreloc;
++ bfd_byte *loc;
++ bfd_vma out_off;
++
++ /* When generating a dynamic object, these relocations
++ are copied into the output file to be resolved at run
++ time. */
++
++ skip = FALSE;
++ relocate = FALSE;
++
++ out_off = _bfd_elf_section_offset (output_bfd, info,
++ input_section, rel->r_offset);
++ if (out_off == (bfd_vma) -1)
++ skip = TRUE;
++ else if (out_off == (bfd_vma) -2)
++ skip = TRUE, relocate = TRUE;
++ out_off += (input_section->output_section->vma
++ + input_section->output_offset);
++ outrel.r_offset = out_off;
++ outrel.r_addend = rel->r_addend;
++
++ if (skip)
++ memset (&outrel, 0, sizeof outrel);
++ else if (!SYMBOL_REFERENCES_LOCAL (info, h))
++ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
++ else
++ {
++ /* This symbol is local, or marked to become local. */
++ outrel.r_addend += relocation;
++ if (r_type == R_SPU_GLOB_DAT)
++ {
++ outrel.r_info = ELF32_R_INFO (0, R_SPU_GLOB_DAT);
++
++ /* Prelink also wants simple and consistent rules
++ for relocs. This make all RELATIVE relocs have
++ *r_offset equal to r_addend. */
++ relocate = TRUE;
++ }
++ else
++ {
++ long indx = 0;
++
++ if (bfd_is_abs_section (sec))
++ ;
++ else if (sec == NULL || sec->owner == NULL)
++ {
++ bfd_set_error (bfd_error_bad_value);
++ return FALSE;
++ }
++ else
++ {
++ asection *osec;
++
++ osec = sec->output_section;
++ indx = elf_section_data (osec)->dynindx;
++
++ /* We are turning this relocation into one
++ against a section symbol, so subtract out
++ the output section's address but not the
++ offset of the input section in the output
++ section. */
++ outrel.r_addend -= osec->vma;
++ }
++
++ outrel.r_info = ELF32_R_INFO (indx, r_type);
++ }
++ }
++
++ sreloc = elf_section_data (input_section)->sreloc;
++ if (sreloc == NULL)
++ abort ();
++
++ loc = sreloc->contents;
++ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
++
++ /* If this reloc is against an external symbol, it will
++ be computed at runtime, so there's no need to do
++ anything now. However, for the sake of prelink ensure
++ that the section contents are a known value. */
++ if (! relocate)
++ {
++ unresolved_reloc = FALSE;
++ /* The value chosen here is quite arbitrary as ld.so
++ ignores section contents except for the special
++ case of .opd where the contents might be accessed
++ before relocation. Choose zero, as that won't
++ cause reloc overflow. */
++ relocation = 0;
++ rel->r_addend = 0;
++ /* Adjust pc_relative relocs to have zero in *r_offset. */
++ if (howto->pc_relative)
++ rel->r_addend = (input_section->output_section->vma
++ + input_section->output_offset
++ + rel->r_offset);
++ }
++ }
++ break;
++ }
++
++ if (unresolved_reloc
++ && !((input_section->flags & SEC_DEBUGGING) != 0
++ && h->def_dynamic))
++ {
++ (*_bfd_error_handler)
++ (_("%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
++ input_bfd,
++ bfd_get_section_name (input_bfd, input_section),
++ (long) rel->r_offset,
++ howto->name,
++ sym_name);
++ ret = FALSE;
++ }
++
++ r = _bfd_final_link_relocate (howto,
++ input_bfd,
++ input_section,
++ contents,
++ rel->r_offset, relocation, rel->r_addend);
++
++ if (r != bfd_reloc_ok)
++ {
++ const char *name;
++ const char *msg = (const char *) 0;
++
++ if (h != NULL)
++ name = h->root.root.string;
++ else
++ {
++ name = (bfd_elf_string_from_elf_section
++ (input_bfd, symtab_hdr->sh_link, sym->st_name));
++ if (name == NULL || *name == '\0')
++ name = bfd_section_name (input_bfd, sec);
++ }
++
++ switch (r)
++ {
++ case bfd_reloc_overflow:
++ if (!((*info->callbacks->reloc_overflow)
++ (info, (h ? &h->root : NULL), name, howto->name,
++ (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
++ return FALSE;
++ break;
++
++ case bfd_reloc_undefined:
++ if (!((*info->callbacks->undefined_symbol)
++ (info, name, input_bfd, input_section,
++ rel->r_offset, TRUE)))
++ return FALSE;
++ break;
++
++ case bfd_reloc_outofrange:
++ msg = _("internal error: out of range error");
++ goto common_error;
++
++ case bfd_reloc_notsupported:
++ msg = _("internal error: unsupported relocation error");
++ goto common_error;
++
++ case bfd_reloc_dangerous:
++ msg = _("internal error: dangerous error");
++ goto common_error;
++
++ default:
++ msg = _("internal error: unknown error");
++ /* fall through */
++
++ common_error:
++ if (!((*info->callbacks->warning)
++ (info, msg, name, input_bfd, input_section,
++ rel->r_offset)))
++ return FALSE;
++ break;
++ }
++ }
++ }
++
++ return ret;
++}
++
++static asection *
++spu_elf_gc_mark_hook (asection *sec,
++ struct bfd_link_info *info ATTRIBUTE_UNUSED,
++ Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, struct elf_link_hash_entry *h,
++ Elf_Internal_Sym *sym)
++{
++ if (h != NULL)
++ {
++ switch (h->root.type)
++ {
++ case bfd_link_hash_defined:
++ case bfd_link_hash_defweak:
++ return h->root.u.def.section;
++
++ case bfd_link_hash_common:
++ return h->root.u.c.p->section;
++
++ default:
++ break;
++ }
++ }
++ else
++ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
++
++ return NULL;
++}
++
++static bfd_boolean
++spu_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info ATTRIBUTE_UNUSED,
++ asection *sec ATTRIBUTE_UNUSED, const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
++{
++ return TRUE;
++}
++
++static void
++spu_elf_final_write_processing (bfd * abfd,
++ bfd_boolean linker ATTRIBUTE_UNUSED)
++{
++ elf_elfheader (abfd)->e_machine = EM_SPU;
++
++ /* We do these verifications here because this function is called only
++ * once. There may be a better place to do it, I didn't look. */
++
++ BFD_ASSERT (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32);
++ BFD_ASSERT (elf_elfheader (abfd)->e_ident[EI_DATA] == ELFDATA2MSB);
++ BFD_ASSERT (elf_elfheader (abfd)->e_flags == 0);
++
++ /* Verify that elf_howto_table is in the correct order. */
++ {
++ unsigned int i;
++ for (i = 0; i < sizeof (elf_howto_table) / sizeof (*elf_howto_table); i++)
++ {
++ BFD_ASSERT (elf_howto_table[i].type == i);
++ }
++ }
++}
++
++
++#if defined(BPA)
++static void
++spu_elf_post_process_headers (bfd * abfd, struct bfd_link_info *link_info)
++{
++ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
++
++ /* e_type is set if -plugin assigned. */
++
++ i_ehdrp = elf_elfheader (abfd);
++
++ if (link_info != NULL)
++ {
++ if (link_info->spuplugin)
++ {
++ i_ehdrp->e_type = ET_DYN;
++ }
++ }
++}
++
++#endif
++
++#if defined(BPA)
++static bfd_boolean
++spu_elf_section_processing (bfd * abfd ATTRIBUTE_UNUSED,
++ Elf_Internal_Shdr * i_shdrp)
++{
++ /* Content of PT_NOTE segment for SPU plugin is set here.
++ Because it doesn't have SEC_ALLOC attribute,
++ it is not written in file as usual process.
++
++ If this routine is not used, some special writing process has to be done somewhere.
++ (e.g., special function would be needed as string table writing process.) */
++
++ asection *sec;
++
++ sec = i_shdrp->bfd_section;
++ if ((sec != NULL) &&
++ (sec->name != NULL) && (strcmp (sec->name, SPU_PTNOTE_SPUNAME) == 0))
++ {
++
++ SPUPLUGIN_INFO *spuplugin_info;
++ spuplugin_info = bfd_alloc (abfd, sizeof (SPUPLUGIN_INFO));
++
++ bfd_put_32(abfd, (bfd_vma) SPU_PLUGIN_NAMESZ, &spuplugin_info->namesz) ;
++ bfd_put_32(abfd, (bfd_vma) SPU_PLUGIN_LOOKUPNAMESZ, &spuplugin_info->descsz) ;
++ bfd_put_32(abfd, (bfd_vma) 1, &spuplugin_info->type) ;
++ strncpy( spuplugin_info->name, SPU_PLUGIN_NAME, SPU_PLUGIN_NAMESZ);
++ strncpy( spuplugin_info->lookupname, bfd_get_filename(abfd), SPU_PLUGIN_LOOKUPNAMESZ);
++
++ i_shdrp->contents = (unsigned char*)spuplugin_info ;
++ }
++ return TRUE;
++}
++#endif
++
++#if defined(BPA)
++/*
++ * Make SPU_PTNOTE_SPUNAME section
++ * */
++static bfd_boolean
++spu_elf_always_size_sections (bfd * abfd, struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
++{
++
++ register asection *s;
++ char *sname = SPU_PTNOTE_SPUNAME;
++
++ s = bfd_get_section_by_name(abfd, sname);
++ /* don't create the section if already exists */
++ if (s == NULL) {
++ s = bfd_make_section (abfd, sname);
++ if (s == NULL) {
++ return FALSE;
++ }
++ }
++
++ if (!bfd_set_section_flags
++ (abfd, s,
++ (SEC_LOAD | SEC_IN_MEMORY | SEC_HAS_CONTENTS | SEC_LINKER_CREATED |
++ SEC_READONLY))) {
++ return FALSE;
++ }
++
++ if (!bfd_set_section_alignment (abfd, s, 2)) {
++ return FALSE;
++ }
++
++ if (!bfd_set_section_size (abfd, s, sizeof (SPUPLUGIN_INFO))) {
++ return FALSE;
++ }
++
++ return TRUE;
++}
++#endif
++
++static bfd_boolean
++spu_elf_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
++ struct bfd_link_info *info ATTRIBUTE_UNUSED)
++{
++ return TRUE;
++}
++static bfd_boolean
++spu_elf_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
++ struct bfd_link_info *info ATTRIBUTE_UNUSED,
++ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
++ Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
++{
++ return TRUE;
++}
++
++/* compute the sizes of the required dynamic relocatios */
++static bfd_boolean
++allocate_dynrelocs (bfd *abfd, struct bfd_link_info *info,
++ asection *sec, const Elf_Internal_Rela *relocs)
++{
++ Elf_Internal_Shdr *symtab_hdr;
++ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
++ const Elf_Internal_Rela *rel;
++ const Elf_Internal_Rela *rel_end;
++ asection *sreloc;
++ bfd *dynobj;
++
++ if (info->relocatable)
++ return TRUE;
++
++ /* Don't do anything special with non-loaded, non-alloced sections.
++ In particular, there's not much point in propagating relocs to
++ shared libs that the dynamic linker won't relocate. */
++ if ((sec->flags & SEC_ALLOC) == 0)
++ return TRUE;
++
++ /* spu_elf_check_relocs will have set sreloc for the sections we
++ need to check. */
++ sreloc = elf_section_data (sec)->sreloc;
++ if (sreloc == NULL)
++ return TRUE;
++
++ dynobj = elf_hash_table (info)->dynobj;
++ if (dynobj == NULL)
++ abort();
++
++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
++
++ sym_hashes = elf_sym_hashes (abfd);
++ sym_hashes_end = (sym_hashes
++ + symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
++ - symtab_hdr->sh_info);
++
++
++ rel_end = relocs + sec->reloc_count;
++ for (rel = relocs; rel < rel_end; rel++)
++ {
++ unsigned long r_symndx;
++ struct elf_link_hash_entry *h;
++ enum elf_spu_reloc_type r_type;
++
++ r_symndx = ELF32_R_SYM (rel->r_info);
++ if (r_symndx < symtab_hdr->sh_info)
++ h = NULL;
++ else
++ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
++
++ r_type = ELF32_R_TYPE (rel->r_info);
++ switch (r_type)
++ {
++ case R_SPU_ADDR10:
++ case R_SPU_ADDR16:
++ case R_SPU_ADDR16_HI:
++ case R_SPU_ADDR16_LO:
++ case R_SPU_ADDR18:
++ case R_SPU_GLOB_DAT:
++ case R_SPU_REL16:
++ case R_SPU_ADDR7:
++ case R_SPU_ADDR10I:
++ case R_SPU_ADDR16I:
++ if ((info->shared
++ && (h == NULL
++ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
++ || h->root.type != bfd_link_hash_undefweak)
++ && (!SYMBOL_CALLS_LOCAL (info, h)))
++ || (!info->shared
++ && h != NULL
++ && h->dynindx != -1
++ && h->def_dynamic
++ && !h->def_regular))
++ {
++ /* We must copy these reloc types into the output file.
++ Increase the size of the reloc section. */
++ sreloc->rawsize += sizeof (Elf32_External_Rela);
++ }
++ break;
++
++ default:
++ break;
++ }
++ }
++ return TRUE;
++}
++
++/* Set the sizes of the dynamic sections. */
++
++static bfd_boolean
++spu_elf_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info * info)
++{
++ bfd * dynobj;
++ asection * s;
++ bfd_boolean relocs;
++ bfd_boolean reltext;
++ asection *o;
++ bfd *inputobj;
++
++ /* Check all the relocations of all input objects to determine
++ the size of dynamic sections. */
++ for (inputobj = info->input_bfds;
++ inputobj;
++ inputobj = inputobj->link_next)
++ {
++ for (o = inputobj->sections; o != NULL; o = o->next)
++ {
++ Elf_Internal_Rela *internal_relocs;
++ bfd_boolean ok;
++
++ if ((o->flags & SEC_RELOC) == 0
++ || o->reloc_count == 0
++ || ((info->strip == strip_all || info->strip == strip_debugger)
++ && (o->flags & SEC_DEBUGGING) != 0)
++ || bfd_is_abs_section (o->output_section))
++ continue;
++
++ internal_relocs = _bfd_elf_link_read_relocs (inputobj, o, NULL, NULL,
++ info->keep_memory);
++ if (internal_relocs == NULL)
++ return FALSE;
++
++ ok = allocate_dynrelocs (inputobj, info, o, internal_relocs);
++
++ if (elf_section_data (o)->relocs != internal_relocs)
++ free (internal_relocs);
++
++ if (! ok)
++ return FALSE;
++ }
++ }
++
++ dynobj = elf_hash_table (info)->dynobj;
++ BFD_ASSERT (dynobj != NULL);
++
++ /* The code above has determined the sizes of the various dynamic
++ sections. Allocate memory for them. */
++ relocs = FALSE;
++ reltext = FALSE;
++ for (s = dynobj->sections; s != NULL; s = s->next)
++ {
++ const char * name;
++ bfd_boolean strip;
++
++ if ((s->flags & SEC_LINKER_CREATED) == 0)
++ continue;
++
++ if (s->contents != NULL)
++ continue;
++
++ /* It's OK to base decisions on the section name, because none
++ of the dynobj section names depend upon the input files. */
++ name = bfd_get_section_name (dynobj, s);
++
++ strip = FALSE;
++
++ if (strncmp (name, ".rela", 5) == 0)
++ {
++ if (s->rawsize == 0)
++ {
++ /* If we don't need this section, strip it from the output
++ file. */
++ strip = TRUE;
++ }
++ else
++ {
++ /* We use the reloc_count field as a counter if we need
++ to copy relocs into the output file. */
++ s->reloc_count = 0;
++ }
++ }
++ else
++ /* It's not one of our sections, so don't allocate space. */
++ continue;
++
++ if (strip)
++ {
++ s->flags |= SEC_EXCLUDE;
++ continue;
++ }
++
++ /* Allocate memory for the section contents. We use bfd_zalloc
++ here in case unused entries are not reclaimed before the
++ section's contents are written out. This should not happen,
++ but this way if it does, we get a R_SPU_NONE reloc instead of
++ garbage. */
++ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->rawsize);
++ if (s->contents == NULL && s->rawsize != 0)
++ return FALSE;
++ }
++
++ return TRUE;
++}
++
++/* Create dynamic sections when linking against a dynamic object. */
++
++static bfd_boolean
++spu_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
++{
++ flagword flags;
++ asection *s;
++ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
++
++ /* We need to create .dynbss, and .rel[a].bss sections. */
++
++ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
++ | SEC_LINKER_CREATED);
++
++ if (bed->want_dynbss)
++ {
++ /* The .dynbss section is a place to put symbols which are defined
++ by dynamic objects, are referenced by regular objects, and are
++ not functions. We must allocate space for them in the process
++ image and use a R_*_COPY reloc to tell the dynamic linker to
++ initialize them at run time. The linker script puts the .dynbss
++ section into the .bss section of the final image. */
++ s = bfd_make_section (abfd, ".dynbss");
++ if (s == NULL
++ || ! bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED))
++ return FALSE;
++
++ /* The .rel[a].bss section holds copy relocs. This section is not
++ normally needed. We need to create it here, though, so that the
++ linker will map it to an output section. We can't just create it
++ only if we need it, because we will not know whether we need it
++ until we have seen all the input files, and the first time the
++ main linker code calls BFD after examining all the input files
++ (size_dynamic_sections) the input sections have already been
++ mapped to the output sections. If the section turns out not to
++ be needed, we can discard it later. We will never need this
++ section when generating a shared object, since they do not use
++ copy relocs. */
++ if (! info->shared)
++ {
++ s = bfd_make_section (abfd,
++ (bed->default_use_rela_p
++ ? ".rela.bss" : ".rel.bss"));
++ if (s == NULL
++ || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
++ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
++ return FALSE;
++ }
++ }
++
++ return TRUE;
++}
++
++static bfd_boolean
++spu_elf_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
++ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
++{
++ return TRUE;
++}
++
++
++#define elf_backend_can_gc_sections 1
++#define elf_backend_rela_normal 1
++
++
++#define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
++#define elf_info_to_howto spu_elf_info_to_howto
++#define elf_info_to_howto_rel spu_elf_info_to_howto_rel
++#define elf_backend_relocate_section spu_elf_relocate_section
++#define elf_backend_final_write_processing spu_elf_final_write_processing
++#define elf_backend_gc_mark_hook spu_elf_gc_mark_hook
++#define elf_backend_gc_sweep_hook spu_elf_gc_sweep_hook
++#define elf_backend_adjust_dynamic_symbol spu_elf_adjust_dynamic_symbol
++#define elf_backend_check_relocs spu_elf_check_relocs
++
++#define elf_backend_create_dynamic_sections spu_elf_create_dynamic_sections
++#define elf_backend_finish_dynamic_sections spu_elf_finish_dynamic_sections
++#define elf_backend_finish_dynamic_symbol spu_elf_finish_dynamic_symbol
++#define elf_backend_size_dynamic_sections spu_elf_size_dynamic_sections
++
++#define TARGET_BIG_SYM bfd_elf32_spu_vec
++#define TARGET_BIG_NAME "elf32-spu"
++#define ELF_ARCH bfd_arch_spu
++#define ELF_MACHINE_CODE EM_SPU
++#define ELF_MAXPAGESIZE 0x80 /* This matches the alignment need for DMA. */
++
++#if defined(BPA)
++#define elf_backend_post_process_headers spu_elf_post_process_headers
++#define elf_backend_section_processing spu_elf_section_processing
++#define elf_backend_always_size_sections spu_elf_always_size_sections
++#define elf_backend_special_sections spu_elf_special_sections
++#endif
++
++#include "elf32-target.h"
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/elf64-ppc.c binutils/bfd/elf64-ppc.c
+--- binutils-2.16.1/bfd/elf64-ppc.c 2005-06-12 19:37:59.000000000 +0200
++++ binutils/bfd/elf64-ppc.c 2006-03-30 01:23:21.000000000 +0200
+@@ -3967,7 +3967,8 @@
+ newsym->value = 0;
+ newsym->flags = BSF_WEAK;
+
+- bh = NULL;
++ /* We don't want to search the "wrap" hash table */
++ bh = bfd_link_hash_lookup (info->hash, newsym->name, TRUE, FALSE, FALSE);
+ if (!_bfd_generic_link_add_one_symbol (info, abfd, newsym->name,
+ newsym->flags, newsym->section,
+ newsym->value, NULL, FALSE, FALSE,
+@@ -8985,6 +8986,8 @@
+
+ if (stub_type != ppc_stub_plt_call)
+ {
++ /* CELL Local: Fix for lib00001372 in 2.15, not sure
++ if it is necessary in 2.16.1, but leaving it in. */
+ /* Check whether we need a TOC adjusting stub.
+ Since the linker pastes together pieces from
+ different object files when creating the
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/opncls.c binutils/bfd/opncls.c
+--- binutils-2.16.1/bfd/opncls.c 2005-03-07 11:32:38.000000000 +0100
++++ binutils/bfd/opncls.c 2006-03-30 01:23:21.000000000 +0200
+@@ -1357,3 +1357,18 @@
+
+ return TRUE;
+ }
++
++/*
++ * Added at SCEA - set direction. Needed to compensate for WIN32
++ * lack of fcntl
++ */
++void
++bfd_set_direction(bfd *abfd, int fdflags)
++{
++ switch (fdflags & (O_ACCMODE)) {
++ case O_RDONLY: abfd->direction = read_direction; break;
++ case O_WRONLY: abfd->direction = write_direction; break;
++ case O_RDWR: abfd->direction = both_direction; break;
++ default: abort ();
++ }
++}
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/reloc.c binutils/bfd/reloc.c
+--- binutils-2.16.1/bfd/reloc.c 2005-03-02 22:23:21.000000000 +0100
++++ binutils/bfd/reloc.c 2006-03-30 01:23:21.000000000 +0200
+@@ -4159,6 +4159,33 @@
+ Intel i860 Relocations.
+
+ ENUM
++ BFD_RELOC_SPU_IMM7
++ENUMX
++ BFD_RELOC_SPU_IMM8
++ENUMX
++ BFD_RELOC_SPU_IMM10
++ENUMX
++ BFD_RELOC_SPU_IMM10W
++ENUMX
++ BFD_RELOC_SPU_IMM16
++ENUMX
++ BFD_RELOC_SPU_IMM16W
++ENUMX
++ BFD_RELOC_SPU_IMM18
++ENUMX
++ BFD_RELOC_SPU_PCREL9a
++ENUMX
++ BFD_RELOC_SPU_PCREL9b
++ENUMX
++ BFD_RELOC_SPU_PCREL16
++ENUMX
++ BFD_RELOC_SPU_LO16
++ENUMX
++ BFD_RELOC_SPU_HI16
++ENUMDOC
++ SPU Relocations.
++
++ENUM
+ BFD_RELOC_OPENRISC_ABS_26
+ ENUMX
+ BFD_RELOC_OPENRISC_REL_26
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/bfd/targets.c binutils/bfd/targets.c
+--- binutils-2.16.1/bfd/targets.c 2005-03-01 02:56:27.000000000 +0100
++++ binutils/bfd/targets.c 2006-03-30 01:23:21.000000000 +0200
+@@ -613,6 +613,7 @@
+ extern const bfd_target bfd_elf32_shlnbsd_vec;
+ extern const bfd_target bfd_elf32_shnbsd_vec;
+ extern const bfd_target bfd_elf32_sparc_vec;
++extern const bfd_target bfd_elf32_spu_vec;
+ extern const bfd_target bfd_elf32_sparc_vxworks_vec;
+ extern const bfd_target bfd_elf32_tradbigmips_vec;
+ extern const bfd_target bfd_elf32_tradlittlemips_vec;
+@@ -918,6 +919,7 @@
+ &bfd_elf32_sh64blin_vec,
+ #endif
+ &bfd_elf32_sparc_vec,
++ &bfd_elf32_spu_vec,
+ &bfd_elf32_sparc_vxworks_vec,
+ &bfd_elf32_tradbigmips_vec,
+ &bfd_elf32_tradlittlemips_vec,
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/binutils/doc/objcopy.1 binutils/binutils/doc/objcopy.1
+--- binutils-2.16.1/binutils/doc/objcopy.1 2005-04-20 20:49:51.000000000 +0200
++++ binutils/binutils/doc/objcopy.1 2006-03-30 01:23:21.000000000 +0200
+@@ -164,6 +164,8 @@
+ [\fB\-\-change\-section\-vma\fR \fIsection\fR{=,+,\-}\fIval\fR]
+ [\fB\-\-change\-warnings\fR] [\fB\-\-no\-change\-warnings\fR]
+ [\fB\-\-set\-section\-flags\fR \fIsection\fR=\fIflags\fR]
++ [\fB\-\-set\-section\-align\fR \fIsection\fR=\fIalignment\fR]
++ [\fB\-\-set\-section\-pad\fR \fIsection\fR=\fIalignment\fR]
+ [\fB\-\-add\-section\fR \fIsectionname\fR=\fIfilename\fR]
+ [\fB\-\-rename\-section\fR \fIoldname\fR=\fInewname\fR[,\fIflags\fR]]
+ [\fB\-\-change\-leading\-char\fR] [\fB\-\-remove\-leading\-char\fR]
+@@ -526,6 +528,13 @@
+ \&\fBcontents\fR flag of a section which does have contents\*(--just remove
+ the section instead. Not all flags are meaningful for all object file
+ formats.
++.IP "\fB\-\-set\-section\-align\fR \fIsection\fR\fB=\fR\fIalignment\fR" 4
++.IX Item "--set-section-align section=align"
++Set the alignment for the named section to 2**align.
++.IP "\fB\-\-set\-section\-pad\fR \fIsection\fR\fB=\fR\fIalignment\fR" 4
++.IX Item "--set-section-pad section=pad_align"
++Set the size for the named section such that its size is a multiple
++of pad_align.
+ .IP "\fB\-\-add\-section\fR \fIsectionname\fR\fB=\fR\fIfilename\fR" 4
+ .IX Item "--add-section sectionname=filename"
+ Add a new section named \fIsectionname\fR while copying the file. The
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/binutils/objcopy.c binutils/binutils/objcopy.c
+--- binutils-2.16.1/binutils/objcopy.c 2005-03-03 12:46:12.000000000 +0100
++++ binutils/binutils/objcopy.c 2006-03-30 01:23:21.000000000 +0200
+@@ -120,6 +120,10 @@
+ bfd_vma lma_val; /* Amount to change by or set to. */
+ bfd_boolean set_flags; /* Whether to set the section flags. */
+ flagword flags; /* What to set the section flags to. */
++ bfd_boolean set_align; /* Whether to set the section alignment. */
++ int alignment; /* What to set the section alignment to. */
++ bfd_boolean set_pad; /* Whether to set the section alignment. */
++ int pad_align; /* What to set the section alignment to. */
+ };
+
+ static struct section_list *change_sections;
+@@ -249,7 +253,9 @@
+ OPTION_READONLY_TEXT,
+ OPTION_WRITABLE_TEXT,
+ OPTION_PURE,
+- OPTION_IMPURE
++ OPTION_IMPURE,
++ OPTION_SET_SECTION_ALIGN,
++ OPTION_SET_SECTION_PAD
+ };
+
+ /* Options to handle if running as "strip". */
+@@ -336,7 +342,9 @@
+ {"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
+ {"remove-section", required_argument, 0, 'R'},
+ {"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
++ {"set-section-align", required_argument, 0, OPTION_SET_SECTION_ALIGN},
+ {"set-section-flags", required_argument, 0, OPTION_SET_SECTION_FLAGS},
++ {"set-section-pad", required_argument, 0, OPTION_SET_SECTION_PAD},
+ {"set-start", required_argument, 0, OPTION_SET_START},
+ {"srec-len", required_argument, 0, OPTION_SREC_LEN},
+ {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
+@@ -441,6 +449,12 @@
+ Warn if a named section does not exist\n\
+ --set-section-flags <name>=<flags>\n\
+ Set section <name>'s properties to <flags>\n\
++ --set-section-align <name>=<alignment>\n\
++ Set section <name>'s alignment to\n\
++ 2**<alignment>\n\
++ --set-section-pad <name>=<pad_align>\n\
++ Set section <name>'s size to a multiple of\n\
++ <pad_align>\n\
+ --add-section <name>=<file> Add section <name> found in <file> to output\n\
+ --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
+ --change-leading-char Force output format's leading character style\n\
+@@ -1907,6 +1921,8 @@
+ size = bfd_section_size (ibfd, isection);
+ if (copy_byte >= 0)
+ size = (size + interleave - 1) / interleave;
++ if (p != NULL && p->set_pad)
++ size += p->pad_align - (size % p->pad_align);
+ if (! bfd_set_section_size (obfd, osection, size))
+ {
+ err = _("size");
+@@ -1942,9 +1958,18 @@
+
+ osection->lma = lma;
+
++ if (p != NULL && p->set_align)
++ {
++ if (! bfd_set_section_alignment (obfd, osection, p->alignment))
++ {
++ bfd_nonfatal (bfd_get_filename (obfd));
++ return FALSE;
++ }
++ }
++
+ /* FIXME: This is probably not enough. If we change the LMA we
+ may have to recompute the header for the file as well. */
+- if (!bfd_set_section_alignment (obfd,
++ else if (!bfd_set_section_alignment (obfd,
+ osection,
+ bfd_section_alignment (ibfd, isection)))
+ {
+@@ -2816,6 +2841,51 @@
+ }
+ break;
+
++ case OPTION_SET_SECTION_ALIGN:
++ {
++ const char *s;
++ int len;
++ char *name;
++
++ s = strchr (optarg, '=');
++ if (s == NULL)
++ fatal (_("bad format for %s"), "--set-section-align");
++
++ len = s - optarg;
++ name = xmalloc (len + 1);
++ strncpy (name, optarg, len);
++ name[len] = '\0';
++
++ p = find_section_list (name, TRUE);
++
++ p->set_align = TRUE;
++ p->alignment = atoi (s + 1);
++ }
++ break;
++
++ case OPTION_SET_SECTION_PAD:
++ {
++ const char *s;
++ int len;
++ char *name;
++
++ s = strchr (optarg, '=');
++ if (s == NULL)
++ fatal (_("bad format for %s"), "--set-section-align");
++
++ len = s - optarg;
++ name = xmalloc (len + 1);
++ strncpy (name, optarg, len);
++ name[len] = '\0';
++
++ p = find_section_list (name, TRUE);
++
++ p->pad_align = atoi (s + 1);
++ if (p->pad_align > 0)
++ p->set_pad = TRUE;
++ }
++ break;
++
+ case OPTION_RENAME_SECTION:
+ {
+ flagword flags;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/binutils/readelf.c binutils/binutils/readelf.c
+--- binutils-2.16.1/binutils/readelf.c 2005-04-20 20:43:36.000000000 +0200
++++ binutils/binutils/readelf.c 2006-03-30 01:23:21.000000000 +0200
+@@ -102,6 +102,7 @@
+ #include "elf/s390.h"
+ #include "elf/sh.h"
+ #include "elf/sparc.h"
++#include "elf/spu.h"
+ #include "elf/v850.h"
+ #include "elf/vax.h"
+ #include "elf/x86-64.h"
+@@ -723,6 +724,7 @@
+ case EM_XSTORMY16:
+ case EM_CRX:
+ case EM_VAX:
++ case EM_SPU:
+ case EM_IP2K:
+ case EM_IP2K_OLD:
+ case EM_IQ2000:
+@@ -1219,6 +1221,10 @@
+ rtype = elf_vax_reloc_type (type);
+ break;
+
++ case EM_SPU:
++ rtype = elf_spu_reloc_type (type);
++ break;
++
+ case EM_IP2K:
+ case EM_IP2K_OLD:
+ rtype = elf_ip2k_reloc_type (type);
+@@ -1715,6 +1721,7 @@
+ case EM_OR32: return "OpenRISC";
+ case EM_CRX: return "National Semiconductor CRX microprocessor";
+ case EM_DLX: return "OpenDLX";
++ case EM_SPU: return "SPU";
+ case EM_IP2K_OLD:
+ case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
+ case EM_IQ2000: return "Vitesse IQ2000";
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/gas/Makefile.am binutils/gas/Makefile.am
+--- binutils-2.16.1/gas/Makefile.am 2005-03-22 16:31:44.000000000 +0100
++++ binutils/gas/Makefile.am 2006-03-30 01:23:21.000000000 +0200
+@@ -81,6 +81,7 @@
+ sh \
+ sh64 \
+ sparc \
++ spu \
+ tic30 \
+ tic4x \
+ tic54x \
+@@ -279,6 +280,7 @@
+ config/tc-sh.c \
+ config/tc-sh64.c \
+ config/tc-sparc.c \
++ config/tc-spu.c \
+ config/tc-tic30.c \
+ config/tc-tic54x.c \
+ config/tc-vax.c \
+@@ -332,6 +334,7 @@
+ config/tc-sh.h \
+ config/tc-sh64.h \
+ config/tc-sparc.h \
++ config/tc-spu.h \
+ config/tc-tic30.h \
+ config/tc-tic54x.h \
+ config/tc-vax.h \
+@@ -1451,6 +1454,12 @@
+ dwarf2dbg.h $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ $(INCDIR)/opcode/sparc.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+ $(INCDIR)/elf/sparc.h $(INCDIR)/elf/reloc-macros.h
++DEPTC_spu_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
++ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
++ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-spu.h \
++ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
++ $(INCDIR)/opcode/spu.h $(INCDIR)/elf/spu.h $(INCDIR)/elf/reloc-macros.h \
++ $(INCDIR)/opcode/spu-insns.h dwarf2dbg.h
+ DEPTC_tic30_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tic30.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/safe-ctype.h $(INCDIR)/opcode/tic30.h
+@@ -1980,6 +1989,10 @@
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h \
+ dwarf2dbg.h $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+ struc-symbol.h $(INCDIR)/aout/aout64.h
++DEPOBJ_spu_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
++ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
++ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-spu.h \
++ $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h
+ DEPOBJ_tic30_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
+ $(srcdir)/config/tc-tic30.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
+ $(INCDIR)/aout/aout64.h $(INCDIR)/obstack.h
+@@ -2362,6 +2375,9 @@
+ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
+ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-sparc.h \
+ dwarf2dbg.h
++DEP_spu_elf = $(srcdir)/config/obj-elf.h $(INCDIR)/symcat.h \
++ $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
++ $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-spu.h
+ DEP_tic30_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-tic30.h \
+ $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h
+ DEP_tic30_coff = $(srcdir)/config/obj-coff.h $(srcdir)/config/tc-tic30.h \
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/gas/config/tc-ppc.c binutils/gas/config/tc-ppc.c
+--- binutils-2.16.1/gas/config/tc-ppc.c 2005-03-02 14:24:01.000000000 +0100
++++ binutils/gas/config/tc-ppc.c 2006-03-30 01:23:21.000000000 +0200
+@@ -906,6 +912,15 @@
+ ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_64 | PPC_OPCODE_POWER4);
+ }
++ /* -mcellppu and -mppu means assemble for the CELL PPU arhictecrue */
++ /* -mdd1.0, -mdd2.0 and -mdd3.0 are here for completeness. */
++ else if (strcmp (arg, "cellppu") == 0 || strcmp (arg, "ppu") == 0
++ || strcmp (arg, "dd1.0") == 0 || strcmp (arg, "dd2.0") == 0
++ || strcmp (arg, "dd3.0") == 0 )
++ {
++ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_CELLPPU
++ | PPC_OPCODE_ALTIVEC;
++ }
+ /* -mcom means assemble for the common intersection between Power
+ and PowerPC. At present, we just allow the union, rather
+ than the intersection. */
+@@ -1100,6 +1115,7 @@
+ -mppc64bridge generate code for PowerPC 64, including bridge insns\n\
+ -mbooke64 generate code for 64-bit PowerPC BookE\n\
+ -mbooke, mbooke32 generate code for 32-bit PowerPC BookE\n\
++-mcellppu, mppu generate code for CELL PPU architecture\n\
+ -mpower4 generate code for Power4 architecture\n\
+ -mpower5 generate code for Power5 architecture\n\
+ -mcom generate code Power/PowerPC common instructions\n\
+@@ -1134,7 +1150,13 @@
+
+ if ((ppc_cpu & ~PPC_OPCODE_ANY) == 0)
+ {
+- if (ppc_obj64)
++ if (strncmp (default_cpu, "ppu", 2) == 0
++ || strncmp (default_cpu, "cellppu", 6) == 0)
++ {
++ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_CELLPPU
++ | PPC_OPCODE_ALTIVEC;
++ }
++ else if (ppc_obj64)
+ ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+ else if (strncmp (default_os, "aix", 3) == 0
+ && default_os[3] >= '4' && default_os[3] <= '9')
+@@ -1266,7 +1288,7 @@
+ if ((ppc_cpu & PPC_OPCODE_601) != 0
+ && (op->flags & PPC_OPCODE_POWER) != 0)
+ continue;
+-
++
+ as_bad (_("Internal assembler error for instruction %s"),
+ op->name);
+ dup_insn = TRUE;
+@@ -1579,6 +1601,7 @@
+ MAP64 ("highesta", BFD_RELOC_PPC64_HIGHEST_S),
+ MAP64 ("tocbase", BFD_RELOC_PPC64_TOC),
+ MAP64 ("toc", BFD_RELOC_PPC_TOC16),
++ MAP ("sdatoc", BFD_RELOC_PPC_TOC16),
+ MAP64 ("toc@l", BFD_RELOC_PPC64_TOC16_LO),
+ MAP64 ("toc@h", BFD_RELOC_PPC64_TOC16_HI),
+ MAP64 ("toc@ha", BFD_RELOC_PPC64_TOC16_HA),
+@@ -2363,8 +2386,6 @@
+
+ if (ex.X_op == O_illegal)
+ as_bad (_("illegal operand"));
+- else if (ex.X_op == O_absent)
+- as_bad (_("missing operand"));
+ else if (ex.X_op == O_register)
+ {
+ insn = ppc_insert_operand (insn, operand, ex.X_add_number,
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/gas/config/tc-spu.c binutils/gas/config/tc-spu.c
+--- binutils-2.16.1/gas/config/tc-spu.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils/gas/config/tc-spu.c 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,1006 @@
++/* spu.c -- Assembler for the IBM Synergistic Processing Unit (SPU) */
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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 "as.h"
++#include "safe-ctype.h"
++#include "subsegs.h"
++#include "opcode/spu.h"
++#include "dwarf2dbg.h"
++
++const struct spu_opcode spu_opcodes[] = {
++#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
++ { MACFORMAT, (OPCODE) << (32-11), MNEMONIC, ASMFORMAT },
++#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
++ { MACFORMAT, ((OPCODE) << (32-11)) | ((FB) << (32-18)), MNEMONIC, ASMFORMAT },
++#include "opcode/spu-insns.h"
++#undef APUOP
++#undef APUOPFB
++};
++
++static const int spu_num_opcodes =
++ sizeof (spu_opcodes) / sizeof (spu_opcodes[0]);
++
++#define MAX_RELOCS 2
++
++struct spu_insn
++{
++ unsigned int opcode;
++ expressionS exp[MAX_RELOCS];
++ int reloc_arg[MAX_RELOCS];
++ int flag[MAX_RELOCS];
++ enum spu_insns tag;
++};
++
++static const char *get_imm PARAMS ((const char *param, struct spu_insn *insn, int arg));
++static const char *get_reg PARAMS ((const char *param, struct spu_insn *insn, int arg, int accept_expr));
++
++static int calcop PARAMS ((struct spu_opcode *format,
++ const char *param, struct spu_insn *insn));
++
++extern char *myname;
++static struct hash_control *op_hash = NULL;
++
++/* These bits should be turned off in the first address of every segment */
++int md_seg_align = 7;
++
++/* These chars start a comment anywhere in a source file (except inside
++ another comment */
++const char comment_chars[] = "#";
++
++/* These chars only start a comment at the beginning of a line. */
++const char line_comment_chars[] = "#";
++
++/* gods own line continuation char */
++const char line_separator_chars[] = ";";
++
++/* Chars that can be used to separate mant from exp in floating point nums */
++const char EXP_CHARS[] = "eE";
++
++/* Chars that mean this number is a floating point constant */
++/* as in 0f123.456 */
++/* or 0H1.234E-12 (see exp chars above) */
++const char FLT_CHARS[] = "dDfF";
++
++const pseudo_typeS md_pseudo_table[] =
++{
++ {"align", s_align_ptwo, 4},
++ {"def", s_set, 0},
++ {"dfloat", float_cons, 'd'},
++ {"ffloat", float_cons, 'f'},
++ {"global", s_globl, 0},
++ {"half", cons, 2},
++ {"bss", s_lcomm_bytes, 1},
++ {"string", stringer, 1},
++ {"word", cons, 4},
++ /* Force set to be treated as an instruction. */
++ {"set", NULL, 0},
++ {".set", s_set, 0},
++ {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
++ {"loc", dwarf2_directive_loc, 0},
++ {0,0,0}
++};
++
++void
++md_begin ()
++{
++ const char *retval = NULL;
++ int i;
++
++ /* initialize hash table */
++
++ op_hash = hash_new ();
++
++ /* loop until you see the end of the list */
++
++ for (i = 0; i < spu_num_opcodes; i++)
++ {
++ /* hash each mnemonic and record its position */
++
++ retval = hash_insert (op_hash, spu_opcodes[i].mnemonic, (PTR)&spu_opcodes[i]);
++
++ if (retval != NULL && strcmp(retval, "exists") != 0)
++ as_fatal (_("Can't hash instruction '%s':%s"),
++ spu_opcodes[i].mnemonic, retval);
++ }
++}
++
++CONST char *md_shortopts = "";
++struct option md_longopts[] = {
++#define OPTION_APUASM (OPTION_MD_BASE)
++ {"apuasm", no_argument, NULL, OPTION_APUASM},
++#define OPTION_DD2 (OPTION_MD_BASE+1)
++ {"mdd2.0", no_argument, NULL, OPTION_DD2},
++#define OPTION_DD1 (OPTION_MD_BASE+2)
++ {"mdd1.0", no_argument, NULL, OPTION_DD1},
++#define OPTION_DD3 (OPTION_MD_BASE+3)
++ {"mdd3.0", no_argument, NULL, OPTION_DD3},
++ { NULL, no_argument, NULL, 0 }
++};
++size_t md_longopts_size = sizeof (md_longopts);
++
++/* When set (by -apuasm) our assembler emulates the behaviour of apuasm.
++ * e.g. don't add bias to float conversion and don't right shift
++ * immediate values. */
++static int emulate_apuasm;
++
++/* Use the dd2.0 instructions set. The only differences are some new
++ * register names and the orx insn */
++static int use_dd2 = 1;
++
++int
++md_parse_option (c, arg)
++ int c;
++ char *arg ATTRIBUTE_UNUSED;
++{
++ switch(c)
++ {
++ case OPTION_APUASM: emulate_apuasm = 1; break;
++ case OPTION_DD3: use_dd2 = 1; break;
++ case OPTION_DD2: use_dd2 = 1; break;
++ case OPTION_DD1: use_dd2 = 0; break;
++ default: return 0;
++ }
++ return 1;
++}
++
++void
++md_show_usage (stream)
++ FILE *stream;
++{
++ fputs (_("\
++SPU options:\n\
++ --apuasm emulate behaviour of apuasm\n"),
++ stream);
++}
++
++
++struct arg_encode {
++ int size;
++ int pos;
++ int rshift;
++ int lo, hi;
++ int wlo, whi;
++ bfd_reloc_code_real_type reloc;
++};
++static struct arg_encode arg_encode[A_MAX] = {
++ { 7, 0, 0, 0, 127, 0, -1, 0 }, /* A_T */
++ { 7, 7, 0, 0, 127, 0, -1, 0 }, /* A_A */
++ { 7, 14, 0, 0, 127, 0, -1, 0 }, /* A_B */
++ { 7, 21, 0, 0, 127, 0, -1, 0 }, /* A_C */
++ { 7, 7, 0, 0, 127, 0, -1, 0 }, /* A_S */
++ { 7, 7, 0, 0, 127, 0, -1, 0 }, /* A_H */
++ { 0, 0, 0, 0, -1, 0, -1, 0 }, /* A_P */
++ { 7, 14, 0, 0, -1, 0, -1, BFD_RELOC_SPU_IMM7 }, /* A_S3 */
++ { 7, 14, 0, -32, 31, -31, 0, BFD_RELOC_SPU_IMM7 }, /* A_S6 */
++ { 7, 14, 0, 0, -1, 0, -1, BFD_RELOC_SPU_IMM7 }, /* A_S7N */
++ { 7, 14, 0, -64, 63, -63, 0, BFD_RELOC_SPU_IMM7 }, /* A_S7 */
++ { 8, 14, 0, 0, 127, 0, -1, BFD_RELOC_SPU_IMM8 }, /* A_U7A */
++ { 8, 14, 0, 0, 127, 0, -1, BFD_RELOC_SPU_IMM8 }, /* A_U7B */
++ { 10, 14, 0, -512, 511, -128, 255, BFD_RELOC_SPU_IMM10 }, /* A_S10B */
++ { 10, 14, 0, -512, 511, 0, -1, BFD_RELOC_SPU_IMM10 }, /* A_S10 */
++ { 2, 23, 9, -1024, 1023, 0, -1, BFD_RELOC_SPU_PCREL9a }, /* A_S11 */
++ { 2, 14, 9, -1024, 1023, 0, -1, BFD_RELOC_SPU_PCREL9b }, /* A_S11I */
++ { 10, 14, 4, -8192, 8191, 0, -1, BFD_RELOC_SPU_IMM10W }, /* A_S14 */
++ { 16, 7, 0, -32768, 32767, 0, -1, BFD_RELOC_SPU_IMM16 }, /* A_S16 */
++ { 16, 7, 2, -131072, 262143, 0, -1, BFD_RELOC_SPU_IMM16W }, /* A_S18 */
++ { 16, 7, 2, -262144, 262143, 0, -1, BFD_RELOC_SPU_PCREL16 }, /* A_R18 */
++ { 7, 14, 0, 0, -1, 0, -1, BFD_RELOC_SPU_IMM7 }, /* A_U3 */
++ { 7, 14, 0, 0, 127, 0, 31, BFD_RELOC_SPU_IMM7 }, /* A_U5 */
++ { 7, 14, 0, 0, 127, 0, 63, BFD_RELOC_SPU_IMM7 }, /* A_U6 */
++ { 7, 14, 0, 0, -1, 0, -1, BFD_RELOC_SPU_IMM7 }, /* A_U7 */
++ { 14, 0, 0, 0, 16383, 0, -1, 0 }, /* A_U14 */
++ { 16, 7, 0, -32768, 65535, 0, -1, BFD_RELOC_SPU_IMM16 }, /* A_X16 */
++ { 18, 7, 0, 0, 262143, 0, -1, BFD_RELOC_SPU_IMM18 }, /* A_U18 */
++};
++
++/* Some flags for handling errors. This is very hackish and added after
++ * the fact. */
++static int syntax_error_arg;
++static char * syntax_error_param;
++static int syntax_reg;
++
++static char *
++insn_fmt_string(struct spu_opcode *format)
++{
++ static char buf[64];
++ int len = 0;
++ int i;
++ int paren;
++ len += sprintf (&buf[len], "%s\t", format->mnemonic);
++ for (i = 1; i <= format->arg[0]; i++)
++ {
++ int arg = format->arg[i];
++ char *exp;
++ if (i > 1 && arg != A_P && format->arg[i-1] != A_P)
++ buf[len++] = ',';
++ if (arg == A_P)
++ exp = "(";
++ else if (arg < A_P)
++ exp = i == syntax_error_arg ? "REG" : "reg";
++ else
++ exp = i == syntax_error_arg ? "IMM" : "imm";
++ len += sprintf (&buf[len], "%s", exp);
++ if (i > 1 && format->arg[i-1] == A_P)
++ buf[len++] = ')';
++ }
++ buf[len] = 0;
++ return buf;
++}
++
++void
++md_assemble (op)
++ char *op;
++{
++ char *param, *thisfrag;
++ char c;
++ struct spu_opcode *format;
++ struct spu_insn insn;
++ int i;
++
++ assert (op);
++
++ /* skip over instruction to find parameters */
++
++ for (param = op; *param != 0 && !ISSPACE (*param); param++)
++ ;
++ c = *param;
++ *param = 0;
++
++ if (c != 0 && c != '\n')
++ param++;
++
++ /* try to find the instruction in the hash table */
++
++ if ((format = (struct spu_opcode *) hash_find (op_hash, op)) == NULL)
++ {
++ as_bad (_("Invalid mnemonic '%s'"), op);
++ return;
++ }
++
++ if (!use_dd2 && strcmp(format->mnemonic, "orx") == 0)
++ {
++ as_bad (_("'%s' is only available in DD2.0 or higher."), op);
++ return;
++ }
++
++ while (1)
++ {
++ /* try parsing this instruction into insn */
++
++ for (i = 0; i < MAX_RELOCS; i++)
++ {
++ insn.exp[i].X_add_symbol = 0;
++ insn.exp[i].X_op_symbol = 0;
++ insn.exp[i].X_add_number = 0;
++ insn.exp[i].X_op = O_illegal;
++ insn.reloc_arg[i] = -1;
++ insn.flag[i] = 0;
++ }
++ insn.opcode = format->opcode;
++ insn.tag = (enum spu_insns)(format - spu_opcodes);
++
++ syntax_error_arg = 0;
++ syntax_error_param = 0;
++ syntax_reg = 0;
++ if (calcop (format, param, &insn))
++ break;
++
++ /* if it doesn't parse try the next instruction */
++ if (!strcmp (format[0].mnemonic, format[1].mnemonic))
++ format++;
++ else
++ {
++ int parg = format[0].arg[syntax_error_arg-1];
++ char *exp;
++ as_fatal (_("Error in argument %d. Expecting: \"%s\""),
++ syntax_error_arg - (parg == A_P),
++ insn_fmt_string(format));
++ return;
++ }
++ }
++
++ if ((syntax_reg & 4)
++ && ! (insn.tag == M_RDCH
++ || insn.tag == M_RCHCNT
++ || insn.tag == M_WRCH))
++ as_warn (_("Mixing register syntax, with and without '$'."));
++ if (syntax_error_param)
++ {
++ char *d = syntax_error_param;
++ while (*d != '$')
++ d--;
++ as_warn (_("Treating '%-*s' as a symbol."), syntax_error_param-d, d);
++ }
++
++ /* grow the current frag and plop in the opcode */
++
++ thisfrag = frag_more (4);
++ md_number_to_chars (thisfrag, insn.opcode, 4);
++
++ /* if this instruction requires labels mark it for later */
++
++ for (i = 0; i < MAX_RELOCS; i++)
++ if (insn.reloc_arg[i] >= 0)
++ {
++ fixS *fixP;
++ bfd_reloc_code_real_type reloc = arg_encode[insn.reloc_arg[i]].reloc;
++ int pcrel = 0;
++ if (reloc == BFD_RELOC_SPU_PCREL9a
++ || reloc == BFD_RELOC_SPU_PCREL9b
++ || reloc == BFD_RELOC_SPU_PCREL16)
++ pcrel = 1;
++ if (insn.flag[i] & 1) reloc = BFD_RELOC_SPU_HI16;
++ else if (insn.flag[i] & 2) reloc = BFD_RELOC_SPU_LO16;
++ fixP = fix_new_exp (frag_now,
++ thisfrag - frag_now->fr_literal,
++ 4,
++ &insn.exp[i],
++ pcrel,
++ reloc);
++ fixP->tc_fix_data = insn.reloc_arg[i];
++ }
++ dwarf2_emit_insn(4);
++}
++
++static int
++calcop (format, param, insn)
++ struct spu_opcode *format;
++ const char *param;
++ struct spu_insn *insn;
++{
++ int i;
++ int paren = 0;
++ int arg;
++
++ for (i = 1; i <= format->arg[0]; i++)
++ {
++ arg = format->arg[i];
++ syntax_error_arg = i;
++
++ while (ISSPACE(*param))
++ param++;
++ if (*param == 0 || *param == ',')
++ return 0;
++ if (arg < A_P)
++ param = get_reg (param, insn, arg, 1);
++ else if (arg > A_P)
++ param = get_imm (param, insn, arg);
++ else if (arg == A_P)
++ {
++ paren++;
++ if ('(' != *param++)
++ return 0;
++ }
++
++ if (!param)
++ return 0;
++
++ while (ISSPACE(*param))
++ param++;
++
++ if (arg != A_P && paren)
++ {
++ paren--;
++ if (')' != *param++)
++ return 0;
++ }
++ else if (i < format->arg[0]
++ && format->arg[i] != A_P
++ && format->arg[i+1] != A_P)
++ {
++ if (',' != *param++)
++ {
++ syntax_error_arg++;
++ return 0;
++ }
++ }
++ }
++ while (ISSPACE(*param))
++ param++;
++ return !paren && (*param == 0 || *param == '\n');
++}
++
++struct reg_name {
++ int regno;
++ int length;
++ char name[32];
++};
++#define REG_NAME(NO,NM) { NO, sizeof(NM)-1, NM }
++static struct reg_name reg_name[] = {
++ REG_NAME(0, "lr"), /* link register */
++ REG_NAME(1, "sp"), /* stack pointer */
++ REG_NAME(0, "rp"), /* link register */
++ REG_NAME(127, "fp"), /* frame pointer */
++};
++static struct reg_name sp_reg_name[] = {
++};
++static struct reg_name ch_reg_name[] = {
++ REG_NAME( 0, "SPU_RdEventStat"),
++ REG_NAME( 1, "SPU_WrEventMask"),
++ REG_NAME( 2, "SPU_WrEventAck"),
++ REG_NAME( 3, "SPU_RdSigNotify1"),
++ REG_NAME( 4, "SPU_RdSigNotify2"),
++ REG_NAME( 7, "SPU_WrDec"),
++ REG_NAME( 8, "SPU_RdDec"),
++ REG_NAME( 11, "SPU_RdEventStatMask"), /* DD2.0 only */
++ REG_NAME( 13, "SPU_RdMachStat"),
++ REG_NAME( 14, "SPU_WrSRR0"),
++ REG_NAME( 15, "SPU_RdSRR0"),
++ REG_NAME( 28, "SPU_WrOutMbox"),
++ REG_NAME( 29, "SPU_RdInMbox"),
++ REG_NAME( 30, "SPU_WrOutIntrMbox"),
++ REG_NAME( 9, "MFC_WrMSSyncReq"),
++ REG_NAME( 12, "MFC_RdTagMask"), /* DD2.0 only */
++ REG_NAME( 16, "MFC_LSA"),
++ REG_NAME( 17, "MFC_EAH"),
++ REG_NAME( 18, "MFC_EAL"),
++ REG_NAME( 19, "MFC_Size"),
++ REG_NAME( 20, "MFC_TagID"),
++ REG_NAME( 21, "MFC_Cmd"),
++ REG_NAME( 22, "MFC_WrTagMask"),
++ REG_NAME( 23, "MFC_WrTagUpdate"),
++ REG_NAME( 24, "MFC_RdTagStat"),
++ REG_NAME( 25, "MFC_RdListStallStat"),
++ REG_NAME( 26, "MFC_WrListStallAck"),
++ REG_NAME( 27, "MFC_RdAtomicStat"),
++};
++#undef REG_NAME
++
++static const char *
++get_reg (param, insn, arg, accept_expr)
++ const char *param;
++ struct spu_insn *insn;
++ int arg;
++ int accept_expr;
++{
++ unsigned regno;
++ int saw_prefix = 0;
++
++ if (*param == '$')
++ {
++ saw_prefix = 1;
++ param++;
++ }
++
++ if (arg == A_H) /* Channel */
++ {
++ if ((param[0] == 'c' || param[0] == 'C')
++ && (param[1] == 'h' || param[1] == 'H')
++ && ISDIGIT(param[2]))
++ param += 2;
++ }
++ else if (arg == A_S) /* Special purpose register */
++ {
++ if ((param[0] == 's' || param[0] == 'S')
++ && (param[1] == 'p' || param[1] == 'P')
++ && ISDIGIT(param[2]))
++ param += 2;
++ }
++
++ if (ISDIGIT(*param))
++ {
++ regno = 0;
++ while (ISDIGIT(*param))
++ regno = regno * 10 + *param++ - '0';
++ }
++ else
++ {
++ struct reg_name *rn;
++ unsigned int i, n, l = 0;
++
++ if (arg == A_H) /* Channel */
++ {
++ rn = ch_reg_name;
++ n = sizeof(ch_reg_name)/sizeof(*ch_reg_name);
++ }
++ else if (arg == A_S) /* Special purpose register */
++ {
++ rn = sp_reg_name;
++ n = sizeof(sp_reg_name)/sizeof(*sp_reg_name);
++ }
++ else
++ {
++ rn = reg_name;
++ n = sizeof(reg_name)/sizeof(*reg_name);
++ }
++ regno = 128;
++ for (i = 0; i < n; i++)
++ if (rn[i].length > l
++ && 0 == strncasecmp(param, rn[i].name, rn[i].length))
++ {
++ l = rn[i].length;
++ regno = rn[i].regno;
++ }
++ param += l;
++ }
++
++ if (!use_dd2
++ && arg == A_H)
++ {
++ if (regno == 11)
++ as_bad (_("'SPU_RdEventStatMask' (channel 11) is only available in DD2.0 or higher."));
++ else if (regno == 12)
++ as_bad (_("'MFC_RdTagMask' (channel 12) is only available in DD2.0 or higher."));
++ }
++
++ if (regno < 128)
++ {
++ insn->opcode |= regno << arg_encode[arg].pos;
++ if ((!saw_prefix && syntax_reg == 1)
++ || (saw_prefix && syntax_reg == 2))
++ syntax_reg |= 4;
++ syntax_reg |= saw_prefix ? 1 : 2;
++ return param;
++ }
++ if (accept_expr)
++ {
++ char *save_ptr;
++ expressionS ex;
++ save_ptr = input_line_pointer;
++ input_line_pointer = (char *)param;
++ expression (&ex);
++ param = input_line_pointer;
++ input_line_pointer = save_ptr;
++ if (ex.X_op == O_register || ex.X_op == O_constant)
++ {
++ insn->opcode |= ex.X_add_number << arg_encode[arg].pos;
++ return param;
++ }
++ }
++ return 0;
++}
++
++static const char *
++get_imm (param, insn, arg)
++ const char *param;
++ struct spu_insn *insn;
++ int arg;
++{
++ int val;
++ char *save_ptr;
++ int low = 0, high = 0;
++ int reloc_i = insn->reloc_arg[0] >= 0 ? 1 : 0;
++
++ if (strncmp(param, "%lo(", 4) == 0)
++ {
++ param += 3;
++ low = 1;
++ as_warn (_("Using old style, %%lo(expr), please change to PPC style, expr@l."));
++ }
++ else if (strncmp(param, "%hi(", 4) == 0)
++ {
++ param += 3;
++ high = 1;
++ as_warn (_("Using old style, %%hi(expr), please change to PPC style, expr@h."));
++ }
++ else if (strncmp(param, "%pic(", 5) == 0)
++ {
++ /* Currently we expect %pic(expr) == expr, so do nothing here.
++ * i.e. for code loaded at address 0 $toc will be 0. */
++ param += 4;
++ }
++
++ if (*param == '$')
++ {
++ /* Symbols can start with $, but if this symbol matches a register
++ * name, it's probably a mistake. The only way to avoid this
++ * warning is to rename the symbol. */
++ struct spu_insn tmp_insn;
++ char *np;
++ if ((np = get_reg (param, &tmp_insn, arg, 0)))
++ syntax_error_param = np;
++ }
++
++ save_ptr = input_line_pointer;
++ input_line_pointer = (char *)param;
++ expression (&insn->exp[reloc_i]);
++ param = input_line_pointer;
++ input_line_pointer = save_ptr;
++
++ /* Similar to ppc_elf_suffix in tc-ppc.c. We have so few cases to
++ * handle we do it inlined here. */
++ if (param[0] == '@' && !ISALNUM(param[2]) && param[2] != '@')
++ {
++ if (param[1] == 'h' || param[1] == 'H')
++ {
++ high = 1;
++ param += 2;
++ }
++ else if (param[1] == 'l' || param[1] == 'L')
++ {
++ low = 1;
++ param += 2;
++ }
++ }
++
++ val = insn->exp[reloc_i].X_add_number;
++
++ if (insn->exp[reloc_i].X_op == O_constant)
++ {
++ if (emulate_apuasm)
++ {
++ /* Convert the value to a format we expect. */
++ val <<= arg_encode[arg].rshift;
++ if (arg == A_U7A)
++ val = 173 - val;
++ else if (arg == A_U7B)
++ val = 155 - val;
++ }
++
++ if (high)
++ val = val >> 16;
++ else if (low)
++ val = val & 0xffff;
++
++ /* Warn about out of range expressions. */
++ {
++ int hi = arg_encode[arg].hi;
++ int lo = arg_encode[arg].lo;
++ int whi = arg_encode[arg].whi;
++ int wlo = arg_encode[arg].wlo;
++ if (hi > lo && (val < lo || val > hi))
++ as_fatal (_("Constant expression %d out of range, [%d, %d]."), val, lo, hi);
++ else if (whi > wlo && (val < wlo || val > whi))
++ as_warn (_("Constant expression %d out of range, [%d, %d]."), val, wlo, whi);
++ }
++
++ if (arg == A_U7A)
++ val = 173 - val;
++ else if (arg == A_U7B)
++ val = 155 - val;
++
++ /* Branch hints have a split encoding. Do the bottom part. */
++ if (arg == A_S11 || arg == A_S11I)
++ insn->opcode |= ((val >> 2) & 0x7f);
++
++ insn->opcode |= ((val >> arg_encode[arg].rshift)
++ & ((1<<arg_encode[arg].size)-1))
++ << arg_encode[arg].pos;
++ insn->reloc_arg[reloc_i] = -1;
++ insn->flag[reloc_i] = 0;
++ }
++ else
++ {
++ insn->reloc_arg[reloc_i] = arg;
++ if (high) insn->flag[reloc_i] |= 1;
++ if (low) insn->flag[reloc_i] |= 2;
++ }
++
++ return param;
++}
++
++void
++md_number_to_chars (buf, val, nbytes)
++ char *buf;
++ valueT val;
++ int nbytes;
++{
++ number_to_chars_bigendian (buf, val, nbytes);
++}
++
++#define MAX_LITTLENUMS 6
++
++/* Turn a string in input_line_pointer into a floating point constant of type
++ type, and store the appropriate bytes in *litP. The number of LITTLENUMS
++ emitted is stored in *sizeP . An error message is returned, or NULL on OK.
++ */
++char *
++md_atof (type, litP, sizeP)
++ char type;
++ char *litP;
++ int *sizeP;
++{
++ int prec;
++ LITTLENUM_TYPE words[MAX_LITTLENUMS];
++ LITTLENUM_TYPE *wordP;
++ char *t;
++
++ switch (type)
++ {
++ case 'f':
++ case 'F':
++ case 's':
++ case 'S':
++ prec = 2;
++ break;
++
++ case 'd':
++ case 'D':
++ case 'r':
++ case 'R':
++ prec = 4;
++ break;
++
++ case 'x':
++ case 'X':
++ prec = 6;
++ break;
++
++ case 'p':
++ case 'P':
++ prec = 6;
++ break;
++
++ default:
++ *sizeP = 0;
++ return _("Bad call to MD_ATOF()");
++ }
++ t = atof_ieee (input_line_pointer, type, words);
++ if (t)
++ input_line_pointer = t;
++
++ *sizeP = prec * sizeof (LITTLENUM_TYPE);
++ for (wordP = words; prec--;)
++ {
++ md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
++ litP += sizeof (LITTLENUM_TYPE);
++ }
++ return 0;
++}
++
++int md_short_jump_size = 4;
++
++void
++md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
++ char *ptr;
++ addressT from_addr ATTRIBUTE_UNUSED, to_addr ATTRIBUTE_UNUSED;
++ fragS *frag;
++ symbolS *to_symbol;
++{
++ ptr[0] = (char) 0xc0;
++ ptr[1] = 0x00;
++ ptr[2] = 0x00;
++ ptr[3] = 0x00;
++ fix_new (frag,
++ ptr - frag->fr_literal,
++ 4,
++ to_symbol,
++ (offsetT) 0,
++ 0,
++ BFD_RELOC_SPU_PCREL16);
++}
++
++int md_long_jump_size = 4;
++
++void
++md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
++ char *ptr;
++ addressT from_addr ATTRIBUTE_UNUSED, to_addr ATTRIBUTE_UNUSED;
++ fragS *frag;
++ symbolS *to_symbol;
++{
++ ptr[0] = (char) 0xc0;
++ ptr[1] = 0x00;
++ ptr[2] = 0x00;
++ ptr[3] = 0x00;
++ fix_new (frag,
++ ptr - frag->fr_literal,
++ 4,
++ to_symbol,
++ (offsetT) 0,
++ 0,
++ BFD_RELOC_SPU_PCREL16);
++}
++
++int
++md_estimate_size_before_relax (fragP, segment_type)
++ fragS *fragP ATTRIBUTE_UNUSED;
++ segT segment_type ATTRIBUTE_UNUSED;
++{
++ as_fatal (_("Relaxation should never occur"));
++ return (-1);
++}
++
++/* If while processing a fixup, a reloc really needs to be created,
++ then it is done here. */
++
++arelent *
++tc_gen_reloc (seg, fixp)
++ asection *seg ATTRIBUTE_UNUSED;
++ fixS *fixp;
++{
++ arelent *reloc;
++ reloc = (arelent *) xmalloc (sizeof (arelent));
++ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
++ if (fixp->fx_addsy)
++ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
++ else if (fixp->fx_subsy)
++ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
++ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
++ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
++ if (reloc->howto == (reloc_howto_type *) NULL)
++ {
++ as_bad_where (fixp->fx_file, fixp->fx_line,
++ _("reloc %d not supported by object file format"),
++ (int) fixp->fx_r_type);
++ return NULL;
++ }
++ reloc->addend = fixp->fx_addnumber;
++ return reloc;
++}
++
++/* Round up a section's size to the appropriate boundary. */
++
++valueT
++md_section_align (seg, size)
++ segT seg;
++ valueT size;
++{
++ int align = bfd_get_section_alignment (stdoutput, seg);
++ valueT mask = ((valueT) 1 << align) - 1;
++
++ return (size + mask) & ~mask;
++}
++
++/* Where a PC relative offset is calculated from. On the spu they
++ are calculated from the beginning of the branch instruction. */
++
++long
++md_pcrel_from (fixp)
++ fixS *fixp;
++{
++ switch (fixp->fx_r_type)
++ {
++ case BFD_RELOC_SPU_PCREL9a:
++ case BFD_RELOC_SPU_PCREL9b:
++ case BFD_RELOC_SPU_PCREL16:
++ return fixp->fx_frag->fr_address + fixp->fx_where;
++ default:
++ abort ();
++ }
++ /*NOTREACHED*/
++}
++
++/* Fill in rs_align_code fragments. */
++
++void
++spu_handle_align (fragp)
++ fragS *fragp;
++{
++ static const unsigned char nop_pattern[8] = {
++ 0x40, 0x20, 0x00, 0x00, /* even nop */
++ 0x00, 0x20, 0x00, 0x00, /* odd nop */
++ };
++
++ int bytes;
++ char *p;
++
++ if (fragp->fr_type != rs_align_code)
++ return;
++
++ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
++ p = fragp->fr_literal + fragp->fr_fix;
++
++ if (bytes & 3)
++ {
++ int fix = bytes & 3;
++ memset (p, 0, fix);
++ p += fix;
++ bytes -= fix;
++ fragp->fr_fix += fix;
++ }
++ if (bytes & 4)
++ {
++ memcpy (p, &nop_pattern[4], 4);
++ p += 4;
++ bytes -= 4;
++ fragp->fr_fix += 4;
++ }
++
++ memcpy (p, nop_pattern, 8);
++ fragp->fr_var = 8;
++}
++
++void
++md_apply_fix (fixP, valP, seg)
++ fixS *fixP;
++ valueT * valP;
++ segT seg ATTRIBUTE_UNUSED;
++{
++ unsigned int res;
++ long val = (long)*valP;
++ char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
++
++ if (fixP->fx_addsy != NULL)
++ {
++ /* Hack around bfd_install_relocation brain damage. */
++ if (fixP->fx_pcrel)
++ val += fixP->fx_frag->fr_address + fixP->fx_where;
++ }
++
++ fixP->fx_addnumber = val;
++
++ if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
++ {
++ fixP->fx_done = 1;
++ res = 0;
++ if (fixP->tc_fix_data > A_P)
++ {
++ int hi = arg_encode[fixP->tc_fix_data].hi;
++ int lo = arg_encode[fixP->tc_fix_data].lo;
++ if (hi > lo && (val < lo || val > hi))
++ as_bad_where (fixP->fx_file, fixP->fx_line,
++ "Relocation doesn't fit. (relocation value = 0x%x)",
++ (int) val);
++ }
++ switch (fixP->fx_r_type)
++ {
++ case 0:
++ break;
++ case BFD_RELOC_SPU_IMM7:
++ res = (val & 0x7f) << 14;
++ break;
++ case BFD_RELOC_SPU_IMM8:
++ res = (val & 0xff) << 14;
++ break;
++ case BFD_RELOC_SPU_IMM10:
++ res = (val & 0xcff) << 14;
++ break;
++ case BFD_RELOC_SPU_IMM10W:
++ res = (val & 0xcff0) << 10;
++ break;
++ case BFD_RELOC_SPU_IMM16:
++ res = (val & 0xffff) << 7;
++ break;
++ case BFD_RELOC_SPU_IMM16W:
++ res = (val & 0x3fffc) << 5;
++ break;
++ case BFD_RELOC_SPU_IMM18:
++ res = (val & 0x3ffff) << 7;
++ break;
++ case BFD_RELOC_16:
++#if 0
++ val = fixP->fx_offset;
++ number_to_chars_bigendian (place, val, 2);
++#endif
++ res = val;
++ break;
++ case BFD_RELOC_32:
++ res = val;
++ break;
++ case BFD_RELOC_SPU_PCREL9a:
++ res = ((val & 0x1fc) >> 2) | ((val & 0x600) << 14);
++ break;
++ case BFD_RELOC_SPU_PCREL9b:
++ res = ((val & 0x1fc) >> 2) | ((val & 0x600) << 5);
++ break;
++ case BFD_RELOC_SPU_PCREL16:
++ res = (val & 0x3fffc) << 5;
++ break;
++
++ default:
++ as_bad_where (fixP->fx_file, fixP->fx_line,
++ _("reloc %d not supported by object file format"),
++ (int) fixP->fx_r_type);
++ abort ();
++ }
++ if (res != 0)
++ {
++ place[0] |= (res >> 24) & 0xff;
++ place[1] |= (res >> 16) & 0xff;
++ place[2] |= (res >> 8) & 0xff;
++ place[3] |= (res) & 0xff;
++ }
++ }
++}
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/gas/config/tc-spu.h binutils/gas/config/tc-spu.h
+--- binutils-2.16.1/gas/config/tc-spu.h 1970-01-01 01:00:00.000000000 +0100
++++ binutils/gas/config/tc-spu.h 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,107 @@
++/* spu.h -- Assembler for spu */
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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 TC_SPU
++
++#ifdef OBJ_ELF
++#define TARGET_FORMAT "elf32-spu"
++#define TARGET_ARCH bfd_arch_spu
++#define TARGET_NAME "elf32-spu"
++#endif
++
++#define TARGET_BYTES_BIG_ENDIAN 1
++
++#ifndef TARGET_NAME
++#define TARGET_NAME "coff-spu"
++#endif
++
++#ifndef TARGET_ARCH
++#define TARGET_ARCH bfd_arch_spu
++#endif
++
++#define COFF_MAGIC SPU_MAGIC
++#define BFD_ARCH bfd_arch_spu
++
++#define NEED_FX_R_TYPE
++#define TC_KEEP_FX_OFFSET
++/* #define TC_CONS_RELOC RELOC_32 */
++
++/* If defined, fixS will have a member named tc_fix_data of this type. */
++#define TC_FIX_TYPE int
++#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = 0)
++
++#define TC_FIX_ADJUSTABLE(FIXP) 0
++
++/* Values passed to md_apply_fix3 don't include symbol values. */
++#define MD_APPLY_SYM_VALUE(FIX) 0
++
++/* This expression evaluates to false if the relocation is for a local
++ object for which we still want to do the relocation at runtime.
++ True if we are willing to perform this relocation while building
++ the .o file. This is only used for pcrel relocations. */
++
++#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \
++ ((FIX)->fx_addsy == NULL \
++ || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \
++ && ! S_IS_WEAK ((FIX)->fx_addsy) \
++ && S_IS_DEFINED ((FIX)->fx_addsy) \
++ && ! S_IS_COMMON ((FIX)->fx_addsy)))
++
++/* The spu uses pseudo-ops with no leading period. */
++#define NO_PSEUDO_DOT 1
++
++/* Don't warn on word overflow; it happens on %hi relocs. */
++#undef WARN_SIGNED_OVERFLOW_WORD
++
++#define md_convert_frag(b,s,f) {as_fatal (_("spu convert_frag\n"));}
++
++/* We don't need to do anything special for undefined symbols. */
++#define md_undefined_symbol(s) 0
++
++/* We have no special operand handling. */
++#define md_operand(e)
++
++/* Fill in rs_align_code fragments. */
++extern void spu_handle_align PARAMS ((fragS *));
++#define HANDLE_ALIGN(frag) spu_handle_align (frag)
++
++#define MAX_MEM_FOR_RS_ALIGN_CODE (7 + 8)
++
++#ifdef SPUCOFF
++
++/* Whether a reloc should be output. */
++#define TC_COUNT_RELOC(fixp) ((fixp)->fx_addsy != NULL || (fixp)->fx_subsy != NULL)
++
++/* Get the BFD reloc type to use for a gas fixS structure. */
++#define TC_COFF_FIX2RTYPE(fixp) tc_coff_fix2rtype (fixp)
++
++/* No special hook needed for symbols. */
++#define tc_coff_symbol_emit_hook(s)
++
++/* Align sections to a four byte boundary. */
++#ifndef max
++#define max(a,b) (((a) > (b)) ? (a) : (b))
++#endif
++#define SUB_SEGMENT_ALIGN(SEG) max (section_alignment[(int) (SEG)], 4)
++
++#endif /* SPUCOFF */
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/gas/configure.tgt binutils/gas/configure.tgt
+--- binutils-2.16.1/gas/configure.tgt 2005-01-31 18:18:51.000000000 +0100
++++ binutils/gas/configure.tgt 2006-03-30 01:23:21.000000000 +0200
+@@ -58,6 +58,7 @@
+ pj*) cpu_type=pj endian=big ;;
+ powerpc*le*) cpu_type=ppc endian=little ;;
+ powerpc*) cpu_type=ppc endian=big ;;
++ ppu*) cpu_type=ppc endian=big ;;
+ rs6000*) cpu_type=ppc ;;
+ s390x*) cpu_type=s390 arch=s390x ;;
+ s390*) cpu_type=s390 arch=s390 ;;
+@@ -338,6 +339,7 @@
+ ppc-*-macos*) fmt=coff em=macos ;;
+ ppc-*-nto*) fmt=elf ;;
+ ppc-*-kaos*) fmt=elf ;;
++ ppc-*-lv2*) fmt=elf ;;
+ ppc-*-lynxos*) fmt=elf em=lynx ;;
+
+ s390-*-linux-*) fmt=elf em=linux ;;
+@@ -385,6 +387,9 @@
+ strongarm-*-elf) fmt=elf ;;
+ strongarm-*-kaos*) fmt=elf ;;
+
++ spu-*-elf) fmt=elf bfd_gas=yes ;;
++ spu-*-lv2) fmt=elf bfd_gas=yes ;;
++
+ tic30-*-*aout*) fmt=aout bfd_gas=yes ;;
+ tic30-*-*coff*) fmt=coff bfd_gas=yes ;;
+ tic4x-*-* | c4x-*-*) fmt=coff bfd_gas=yes ;;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/gas/testsuite/gas/sh/sh64/err-dsp.s binutils/gas/testsuite/gas/sh/sh64/err-dsp.s
+--- binutils-2.16.1/gas/testsuite/gas/sh/sh64/err-dsp.s 2004-03-04 02:24:21.000000000 +0100
++++ binutils/gas/testsuite/gas/sh/sh64/err-dsp.s 2004-05-22 01:10:38.000000000 +0200
+@@ -11,5 +11,5 @@
+ .text
+ start:
+ ldc r3,mod ! { dg-error "invalid operands" }
+- ldre @(16,pc) ! { dg-error "opcode not valid for this cpu variant" }
++ ldre @(16,pc) ! { dg-error "unknown opcode" }
+ lds r4,a0 ! { dg-error "invalid operands" }
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/include/bfdlink.h binutils/include/bfdlink.h
+--- binutils-2.16.1/include/bfdlink.h 2005-03-03 12:58:00.000000000 +0100
++++ binutils/include/bfdlink.h 2006-03-30 01:23:21.000000000 +0200
+@@ -416,6 +416,12 @@
+
+ /* Start and end of RELRO region. */
+ bfd_vma relro_start, relro_end;
++
++ /* CELL LOCAL Begin */
++ /* for IBM STI BPA */
++ /* TRUE if SPU file is plugin. */
++ bfd_boolean spuplugin;
++ /* CELL LOCAL End */
+ };
+
+ /* This structures holds a set of callback functions. These are
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/include/dis-asm.h binutils/include/dis-asm.h
+--- binutils-2.16.1/include/dis-asm.h 2005-03-03 12:58:01.000000000 +0100
++++ binutils/include/dis-asm.h 2006-03-30 01:23:21.000000000 +0200
+@@ -263,6 +263,7 @@
+ extern int print_insn_rs6000 (bfd_vma, disassemble_info *);
+ extern int print_insn_s390 (bfd_vma, disassemble_info *);
+ extern int print_insn_sh (bfd_vma, disassemble_info *);
++extern int print_insn_spu (bfd_vma, disassemble_info *);
+ extern int print_insn_tic30 (bfd_vma, disassemble_info *);
+ extern int print_insn_tic4x (bfd_vma, disassemble_info *);
+ extern int print_insn_tic54x (bfd_vma, disassemble_info *);
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/include/elf/common.h binutils/include/elf/common.h
+--- binutils-2.16.1/include/elf/common.h 2004-10-08 15:55:08.000000000 +0200
++++ binutils/include/elf/common.h 2006-03-30 01:23:21.000000000 +0200
+@@ -118,6 +118,7 @@
+ #define EM_PPC 20 /* PowerPC */
+ #define EM_PPC64 21 /* 64-bit PowerPC */
+ #define EM_S390 22 /* IBM S/390 */
++#define EM_SPU 23 /* Sony SPU */
+
+ #define EM_V800 36 /* NEC V800 series */
+ #define EM_FR20 37 /* Fujitsu FR20 */
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/include/elf/spu.h binutils/include/elf/spu.h
+--- binutils-2.16.1/include/elf/spu.h 1970-01-01 01:00:00.000000000 +0100
++++ binutils/include/elf/spu.h 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,87 @@
++/* SPU ELF support for BFD.
++ Copyright 1999, 2000 Free Software Foundation, Inc.
++
++ This file is part of BFD, the Binary File Descriptor library.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software Foundation,
++ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
++
++#ifndef _ELF_SPU_H
++#define _ELF_SPU_H
++
++#include "elf/reloc-macros.h"
++
++/* elf32-spu.c depends on these being consecutive. */
++START_RELOC_NUMBERS (elf_spu_reloc_type)
++ RELOC_NUMBER (R_SPU_NONE, 0)
++ RELOC_NUMBER (R_SPU_ADDR10, 1)
++ RELOC_NUMBER (R_SPU_ADDR16, 2)
++ RELOC_NUMBER (R_SPU_ADDR16_HI, 3)
++ RELOC_NUMBER (R_SPU_ADDR16_LO, 4)
++ RELOC_NUMBER (R_SPU_ADDR18, 5)
++ RELOC_NUMBER (R_SPU_GLOB_DAT, 6)
++ RELOC_NUMBER (R_SPU_REL16, 7)
++ RELOC_NUMBER (R_SPU_ADDR7, 8)
++ RELOC_NUMBER (R_SPU_REL9, 9)
++ RELOC_NUMBER (R_SPU_REL9I, 10)
++ RELOC_NUMBER (R_SPU_ADDR10I, 11)
++ RELOC_NUMBER (R_SPU_ADDR16I, 12)
++END_RELOC_NUMBERS (R_SPU_max)
++
++
++/* Processor specific flags for the ELF header e_flags field. */
++
++#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
++
++ /* CYGNUS local bits below */
++#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag */
++#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib flag */
++
++/* Processor specific section headers, sh_type field */
++
++#define SHT_ORDERED SHT_HIPROC /* Link editor is to sort the \
++ entries in this section \
++ based on the address \
++ specified in the associated \
++ symbol table entry. */
++
++/* Processor specific section flags, sh_flags field */
++
++#define SHF_EXCLUDE 0x80000000 /* Link editor is to exclude \
++ this section from executable \
++ and shared objects that it \
++ builds when those objects \
++ are not to be furhter \
++ relocated. */
++
++#if (defined(BPA))
++/* Program header extensions */
++#define PT_SPU_INFO 0x70000000 /* SPU Dynamic Object Information */
++#endif
++
++/* SPU plugin information */
++#define SPU_PLUGIN_NAMESZ 8
++#define SPU_PLUGIN_NAME "SPUNAME"
++#define SPU_PTNOTE_SPUNAME ".note.spu_name"
++#define SPU_PLUGIN_LOOKUPNAMESZ 32
++
++typedef struct {
++ unsigned long namesz;
++ unsigned long descsz;
++ unsigned long type;
++ char name[SPU_PLUGIN_NAMESZ];
++ char lookupname[SPU_PLUGIN_LOOKUPNAMESZ];
++} SPUPLUGIN_INFO;
++
++#endif /* _ELF_SPU_H */
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/include/opcode/ppc.h binutils/include/opcode/ppc.h
+--- binutils-2.16.1/include/opcode/ppc.h 2004-09-09 14:42:37.000000000 +0200
++++ binutils/include/opcode/ppc.h 2006-03-30 01:23:21.000000000 +0200
+@@ -134,6 +134,9 @@
+ /* Opcode is supported by machine check APU. */
+ #define PPC_OPCODE_RFMCI 0x800000
+
++/* Opcode is suppered by CELL PPU architecture. */
++#define PPC_OPCODE_CELLPPU PPC_OPCODE_CLASSIC
++
+ /* A macro to extract the major opcode from an instruction. */
+ #define PPC_OP(i) (((i) >> 26) & 0x3f)
+
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/include/opcode/spu-insns.h binutils/include/opcode/spu-insns.h
+--- binutils-2.16.1/include/opcode/spu-insns.h 1970-01-01 01:00:00.000000000 +0100
++++ binutils/include/opcode/spu-insns.h 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,412 @@
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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. */
++
++/* SPU Opcode Table
++
++-=-=-= FORMAT =-=-=-
++
++ +----+-------+-------+-------+-------+ +------------+-------+-------+-------+
++RRR | op | RC | RB | RA | RT | RI7 | op | I7 | RA | RT |
++ +----+-------+-------+-------+-------+ +------------+-------+-------+-------+
++ 0 3 1 1 2 3 0 1 1 2 3
++ 0 7 4 1 0 7 4 1
++
++ +-----------+--------+-------+-------+ +---------+----------+-------+-------+
++RI8 | op | I8 | RA | RT | RI10 | op | I10 | RA | RT |
++ +-----------+--------+-------+-------+ +---------+----------+-------+-------+
++ 0 9 1 2 3 0 7 1 2 3
++ 7 4 1 7 4 1
++
++ +----------+-----------------+-------+ +--------+-------------------+-------+
++RI16 | op | I16 | RT | RI18 | op | I18 | RT |
++ +----------+-----------------+-------+ +--------+-------------------+-------+
++ 0 8 2 3 0 6 2 3
++ 4 1 4 1
++
++ +------------+-------+-------+-------+ +-------+--+-----------------+-------+
++RR | op | RB | RA | RT | LBT | op |RO| I16 | RO |
++ +------------+-------+-------+-------+ +-------+--+-----------------+-------+
++ 0 1 1 2 3 0 6 8 2 3
++ 0 7 4 1 4 1
++
++ +------------+----+--+-------+-------+
++ LBTI | op | // |RO| RA | RO |
++ +------------+----+--+-------+-------+
++ 0 1 1 1 2 3
++ 0 5 7 4 1
++
++-=-=-= OPCODE =-=-=-
++
++OPCODE field specifies the most significant 11bit of the instruction. Some formats don't have 11bits for opcode field, and in this
++case, bit field other than op are defined as 0s. For example, opcode of fma instruction which is RRR format is defined as 0x700,
++since 0x700 -> 11'b11100000000, this means opcode is 4'b1110, and other 7bits are defined as 7'b0000000.
++
++-=-=-= ASM_FORMAT =-=-=-
++
++RRR category RI7 category
++ ASM_RRR mnemonic RC, RA, RB, RT ASM_RI4 mnemonic RT, RA, I4
++ ASM_RI7 mnemonic RT, RA, I7
++
++RI8 category RI10 category
++ ASM_RUI8 mnemonic RT, RA, UI8 ASM_AI10 mnemonic RA, I10
++ ASM_RI10 mnemonic RT, RA, R10
++ ASM_RI10IDX mnemonic RT, I10(RA)
++
++RI16 category RI18 category
++ ASM_I16W mnemonic I16W ASM_RI18 mnemonic RT, I18
++ ASM_RI16 mnemonic RT, I16
++ ASM_RI16W mnemonic RT, I16W
++
++RR category LBT category
++ ASM_MFSPR mnemonic RT, SA ASM_LBT mnemonic brinst, brtarg
++ ASM_MTSPR mnemonic SA, RT
++ ASM_NOOP mnemonic LBTI category
++ ASM_RA mnemonic RA ASM_LBTI mnemonic brinst, RA
++ ASM_RAB mnemonic RA, RB
++ ASM_RDCH mnemonic RT, CA
++ ASM_RR mnemonic RT, RA, RB
++ ASM_RT mnemonic RT
++ ASM_RTA mnemonic RT, RA
++ ASM_WRCH mnemonic CA, RT
++
++Note that RRR instructions have the names for RC and RT reversed from
++what's in the ISA, in order to put RT in the same position it appears
++for other formats.
++
++-=-=-= DEPENDENCY =-=-=-
++
++DEPENDENCY filed consists of 5 digits. This represents which register is used as source and which register is used as target.
++The first(most significant) digit is always 0. Then it is followd by RC, RB, RA and RT digits.
++If the digit is 0, this means the corresponding register is not used in the instruction.
++If the digit is 1, this means the corresponding register is used as a source in the instruction.
++If the digit is 2, this means the corresponding register is used as a target in the instruction.
++If the digit is 3, this means the corresponding register is used as both source and target in the instruction.
++For example, fms instruction has 00113 as the DEPENDENCY field. This means RC is not used in this operation, RB and RA are
++used as sources and RT is the target.
++
++-=-=-= PIPE =-=-=-
++
++This field shows which execution pipe is used for the instruction
++
++pipe0 execution pipelines:
++ FP6 SP floating pipeline
++ FP7 integer operations executed in SP floating pipeline
++ FPD DP floating pipeline
++ FX2 FXU pipeline
++ FX3 Rotate/Shift pipeline
++ FXB Byte pipeline
++ NOP No pipeline
++
++pipe1 execution pipelines:
++ BR Branch pipeline
++ LNOP No pipeline
++ LS Load/Store pipeline
++ SHUF Shuffle pipeline
++ SPR SPR/CH pipeline
++
++*/
++
++#define _A0() {0}
++#define _A1(a) {1,a}
++#define _A2(a,b) {2,a,b}
++#define _A3(a,b,c) {3,a,b,c}
++#define _A4(a,b,c,d) {4,a,b,c,d}
++
++/* TAG FORMAT OPCODE MNEMONIC ASM_FORMAT DEPENDENCY PIPE COMMENT */
++/* 0[RC][RB][RA][RT] */
++/* 1:src, 2:target */
++
++APUOP(M_BR, RI16, 0x190, "br", _A1(A_R18), 00000, BR) /* BRel IP<-IP+I16 */
++APUOP(M_BRSL, RI16, 0x198, "brsl", _A2(A_T,A_R18), 00002, BR) /* BRelSetLink RT,IP<-IP,IP+I16 */
++APUOP(M_BRA, RI16, 0x180, "bra", _A1(A_S18), 00000, BR) /* BRAbs IP<-I16 */
++APUOP(M_BRASL, RI16, 0x188, "brasl", _A2(A_T,A_S18), 00002, BR) /* BRAbsSetLink RT,IP<-IP,I16 */
++APUOP(M_FSMBI, RI16, 0x194, "fsmbi", _A2(A_T,A_X16), 00002, SHUF) /* FormSelMask%I RT<-fsm(I16) */
++APUOP(M_LQA, RI16, 0x184, "lqa", _A2(A_T,A_S18), 00002, LS) /* LoadQAbs RT<-M[I16] */
++APUOP(M_LQR, RI16, 0x19C, "lqr", _A2(A_T,A_R18), 00002, LS) /* LoadQRel RT<-M[IP+I16] */
++APUOP(M_STOP, RR, 0x000, "stop", _A0(), 00000, BR) /* STOP stop */
++APUOP(M_STOP2, RR, 0x000, "stop", _A1(A_U14), 00000, BR) /* STOP stop */
++APUOP(M_STOPD, RR, 0x140, "stopd", _A3(A_T,A_A,A_B), 00111, BR) /* STOPD stop (with register dependencies) */
++APUOP(M_LNOP, RR, 0x001, "lnop", _A0(), 00000, LNOP) /* LNOP no_operation */
++APUOP(M_SYNC, RR, 0x002, "sync", _A0(), 00000, BR) /* SYNC flush_pipe */
++APUOP(M_DSYNC, RR, 0x003, "dsync", _A0(), 00000, BR) /* DSYNC flush_store_queue */
++APUOP(M_MFSPR, RR, 0x00c, "mfspr", _A2(A_T,A_S), 00002, SPR) /* MFSPR RT<-SA */
++APUOP(M_RDCH, RR, 0x00d, "rdch", _A2(A_T,A_H), 00002, SPR) /* ReaDCHannel RT<-CA:data */
++APUOP(M_RCHCNT, RR, 0x00f, "rchcnt", _A2(A_T,A_H), 00002, SPR) /* ReaDCHanCouNT RT<-CA:count */
++APUOP(M_HBRA, LBT, 0x080, "hbra", _A2(A_S11,A_S18), 00000, LS) /* HBRA BTB[B9]<-M[I16] */
++APUOP(M_HBRR, LBT, 0x090, "hbrr", _A2(A_S11,A_R18), 00000, LS) /* HBRR BTB[B9]<-M[IP+I16] */
++APUOP(M_BRZ, RI16, 0x100, "brz", _A2(A_T,A_R18), 00001, BR) /* BRZ IP<-IP+I16_if(RT) */
++APUOP(M_BRNZ, RI16, 0x108, "brnz", _A2(A_T,A_R18), 00001, BR) /* BRNZ IP<-IP+I16_if(RT) */
++APUOP(M_BRHZ, RI16, 0x110, "brhz", _A2(A_T,A_R18), 00001, BR) /* BRHZ IP<-IP+I16_if(RT) */
++APUOP(M_BRHNZ, RI16, 0x118, "brhnz", _A2(A_T,A_R18), 00001, BR) /* BRHNZ IP<-IP+I16_if(RT) */
++APUOP(M_STQA, RI16, 0x104, "stqa", _A2(A_T,A_S18), 00001, LS) /* SToreQAbs M[I16]<-RT */
++APUOP(M_STQR, RI16, 0x11C, "stqr", _A2(A_T,A_R18), 00001, LS) /* SToreQRel M[IP+I16]<-RT */
++APUOP(M_MTSPR, RR, 0x10c, "mtspr", _A2(A_S,A_T), 00001, SPR) /* MTSPR SA<-RT */
++APUOP(M_WRCH, RR, 0x10d, "wrch", _A2(A_H,A_T), 00001, SPR) /* ChanWRite CA<-RT */
++APUOP(M_LQD, RI10, 0x1a0, "lqd", _A4(A_T,A_S14,A_P,A_A), 00012, LS) /* LoadQDisp RT<-M[Ra+I10] */
++APUOP(M_BI, RR, 0x1a8, "bi", _A1(A_A), 00010, BR) /* BI IP<-RA */
++APUOP(M_BISL, RR, 0x1a9, "bisl", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
++APUOP(M_IRET, RR, 0x1aa, "iret", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
++APUOP(M_IRET2, RR, 0x1aa, "iret", _A0(), 00010, BR) /* IRET IP<-SRR0 */
++APUOP(M_BISLED, RR, 0x1ab, "bisled", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
++APUOP(M_HBR, LBTI, 0x1ac, "hbr", _A2(A_S11I,A_A), 00010, LS) /* HBR BTB[B9]<-M[Ra] */
++APUOP(M_FREST, RR, 0x1b8, "frest", _A2(A_T,A_A), 00012, SHUF) /* FREST RT<-recip(RA) */
++APUOP(M_FRSQEST, RR, 0x1b9, "frsqest", _A2(A_T,A_A), 00012, SHUF) /* FRSQEST RT<-rsqrt(RA) */
++APUOP(M_FSM, RR, 0x1b4, "fsm", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
++APUOP(M_FSMH, RR, 0x1b5, "fsmh", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
++APUOP(M_FSMB, RR, 0x1b6, "fsmb", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
++APUOP(M_GB, RR, 0x1b0, "gb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
++APUOP(M_GBH, RR, 0x1b1, "gbh", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
++APUOP(M_GBB, RR, 0x1b2, "gbb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
++APUOP(M_CBD, RI7, 0x1f4, "cbd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
++APUOP(M_CHD, RI7, 0x1f5, "chd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
++APUOP(M_CWD, RI7, 0x1f6, "cwd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
++APUOP(M_CDD, RI7, 0x1f7, "cdd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
++APUOP(M_ROTQBII, RI7, 0x1f8, "rotqbii", _A3(A_T,A_A,A_U3), 00012, SHUF) /* ROTQBII RT<-RA<<<I7 */
++APUOP(M_ROTQBYI, RI7, 0x1fc, "rotqbyi", _A3(A_T,A_A,A_S7N), 00012, SHUF) /* ROTQBYI RT<-RA<<<(I7*8) */
++APUOP(M_ROTQMBII, RI7, 0x1f9, "rotqmbii", _A3(A_T,A_A,A_S3), 00012, SHUF) /* ROTQMBII RT<-RA<<I7 */
++APUOP(M_ROTQMBYI, RI7, 0x1fd, "rotqmbyi", _A3(A_T,A_A,A_S6), 00012, SHUF) /* ROTQMBYI RT<-RA<<I7 */
++APUOP(M_SHLQBII, RI7, 0x1fb, "shlqbii", _A3(A_T,A_A,A_U3), 00012, SHUF) /* SHLQBII RT<-RA<<I7 */
++APUOP(M_SHLQBYI, RI7, 0x1ff, "shlqbyi", _A3(A_T,A_A,A_U5), 00012, SHUF) /* SHLQBYI RT<-RA<<I7 */
++APUOP(M_STQD, RI10, 0x120, "stqd", _A4(A_T,A_S14,A_P,A_A), 00011, LS) /* SToreQDisp M[Ra+I10]<-RT */
++APUOP(M_BIHNZ, RR, 0x12b, "bihnz", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
++APUOP(M_BIHZ, RR, 0x12a, "bihz", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
++APUOP(M_BINZ, RR, 0x129, "binz", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
++APUOP(M_BIZ, RR, 0x128, "biz", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
++APUOP(M_CBX, RR, 0x1d4, "cbx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
++APUOP(M_CHX, RR, 0x1d5, "chx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
++APUOP(M_CWX, RR, 0x1d6, "cwx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
++APUOP(M_CDX, RR, 0x1d7, "cdx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
++APUOP(M_LQX, RR, 0x1c4, "lqx", _A3(A_T,A_A,A_B), 00112, LS) /* LoadQindeX RT<-M[Ra+Rb] */
++APUOP(M_ROTQBI, RR, 0x1d8, "rotqbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBI RT<-RA<<<Rb */
++APUOP(M_ROTQMBI, RR, 0x1d9, "rotqmbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBI RT<-RA<<Rb */
++APUOP(M_SHLQBI, RR, 0x1db, "shlqbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBI RT<-RA<<Rb */
++APUOP(M_ROTQBY, RR, 0x1dc, "rotqby", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBY RT<-RA<<<(Rb*8) */
++APUOP(M_ROTQMBY, RR, 0x1dd, "rotqmby", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBY RT<-RA<<Rb */
++APUOP(M_SHLQBY, RR, 0x1df, "shlqby", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBY RT<-RA<<Rb */
++APUOP(M_ROTQBYBI, RR, 0x1cc, "rotqbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBYBI RT<-RA<<Rb */
++APUOP(M_ROTQMBYBI, RR, 0x1cd, "rotqmbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBYBI RT<-RA<<Rb */
++APUOP(M_SHLQBYBI, RR, 0x1cf, "shlqbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBYBI RT<-RA<<Rb */
++APUOP(M_STQX, RR, 0x144, "stqx", _A3(A_T,A_A,A_B), 00111, LS) /* SToreQindeX M[Ra+Rb]<-RT */
++APUOP(M_SHUFB, RRR, 0x580, "shufb", _A4(A_C,A_A,A_B,A_T), 02111, SHUF) /* SHUFfleBytes RC<-f(RA,RB,RT) */
++APUOP(M_IL, RI16, 0x204, "il", _A2(A_T,A_S16), 00002, FX2) /* ImmLoad RT<-sxt(I16) */
++APUOP(M_ILH, RI16, 0x20c, "ilh", _A2(A_T,A_X16), 00002, FX2) /* ImmLoadH RT<-I16 */
++APUOP(M_ILHU, RI16, 0x208, "ilhu", _A2(A_T,A_X16), 00002, FX2) /* ImmLoadHUpper RT<-I16<<16 */
++APUOP(M_ILA, RI18, 0x210, "ila", _A2(A_T,A_U18), 00002, FX2) /* ImmLoadAddr RT<-zxt(I18) */
++APUOP(M_NOP, RR, 0x201, "nop", _A1(A_T), 00000, NOP) /* XNOP no_operation */
++APUOP(M_NOP2, RR, 0x201, "nop", _A0(), 00000, NOP) /* XNOP no_operation */
++APUOP(M_IOHL, RI16, 0x304, "iohl", _A2(A_T,A_X16), 00003, FX2) /* AddImmeXt RT<-RT+sxt(I16) */
++APUOP(M_ANDBI, RI10, 0x0b0, "andbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* AND%I RT<-RA&I10 */
++APUOP(M_ANDHI, RI10, 0x0a8, "andhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* AND%I RT<-RA&I10 */
++APUOP(M_ANDI, RI10, 0x0a0, "andi", _A3(A_T,A_A,A_S10), 00012, FX2) /* AND%I RT<-RA&I10 */
++APUOP(M_ORBI, RI10, 0x030, "orbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* OR%I RT<-RA|I10 */
++APUOP(M_ORHI, RI10, 0x028, "orhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* OR%I RT<-RA|I10 */
++APUOP(M_ORI, RI10, 0x020, "ori", _A3(A_T,A_A,A_S10), 00012, FX2) /* OR%I RT<-RA|I10 */
++APUOP(M_ORX, RR, 0x1f0, "orx", _A2(A_T,A_A), 00012, BR) /* ORX RT<-RA.w0|RA.w1|RA.w2|RA.w3 */
++APUOP(M_XORBI, RI10, 0x230, "xorbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* XOR%I RT<-RA^I10 */
++APUOP(M_XORHI, RI10, 0x228, "xorhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* XOR%I RT<-RA^I10 */
++APUOP(M_XORI, RI10, 0x220, "xori", _A3(A_T,A_A,A_S10), 00012, FX2) /* XOR%I RT<-RA^I10 */
++APUOP(M_AHI, RI10, 0x0e8, "ahi", _A3(A_T,A_A,A_S10), 00012, FX2) /* Add%Immed RT<-RA+I10 */
++APUOP(M_AI, RI10, 0x0e0, "ai", _A3(A_T,A_A,A_S10), 00012, FX2) /* Add%Immed RT<-RA+I10 */
++APUOP(M_SFHI, RI10, 0x068, "sfhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* SubFrom%Imm RT<-I10-RA */
++APUOP(M_SFI, RI10, 0x060, "sfi", _A3(A_T,A_A,A_S10), 00012, FX2) /* SubFrom%Imm RT<-I10-RA */
++APUOP(M_CGTBI, RI10, 0x270, "cgtbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CGT%I RT<-(RA>I10) */
++APUOP(M_CGTHI, RI10, 0x268, "cgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */
++APUOP(M_CGTI, RI10, 0x260, "cgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */
++APUOP(M_CLGTBI, RI10, 0x2f0, "clgtbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
++APUOP(M_CLGTHI, RI10, 0x2e8, "clgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
++APUOP(M_CLGTI, RI10, 0x2e0, "clgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
++APUOP(M_CEQBI, RI10, 0x3f0, "ceqbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
++APUOP(M_CEQHI, RI10, 0x3e8, "ceqhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
++APUOP(M_CEQI, RI10, 0x3e0, "ceqi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
++APUOP(M_HGTI, RI10, 0x278, "hgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */
++APUOP(M_HGTI2, RI10, 0x278, "hgti", _A2(A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */
++APUOP(M_HLGTI, RI10, 0x2f8, "hlgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */
++APUOP(M_HLGTI2, RI10, 0x2f8, "hlgti", _A2(A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */
++APUOP(M_HEQI, RI10, 0x3f8, "heqi", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */
++APUOP(M_HEQI2, RI10, 0x3f8, "heqi", _A2(A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */
++APUOP(M_MPYI, RI10, 0x3a0, "mpyi", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYI RT<-RA*I10 */
++APUOP(M_MPYUI, RI10, 0x3a8, "mpyui", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYUI RT<-RA*I10 */
++APUOP(M_CFLTS, RI8, 0x3b0, "cflts", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTS RT<-int(RA,I8) */
++APUOP(M_CFLTU, RI8, 0x3b2, "cfltu", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTU RT<-int(RA,I8) */
++APUOP(M_CSFLT, RI8, 0x3b4, "csflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CSFLT RT<-flt(RA,I8) */
++APUOP(M_CUFLT, RI8, 0x3b6, "cuflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CUFLT RT<-flt(RA,I8) */
++APUOP(M_FESD, RR, 0x3b8, "fesd", _A2(A_T,A_A), 00012, FPD) /* FESD RT<-double(RA) */
++APUOP(M_FRDS, RR, 0x3b9, "frds", _A2(A_T,A_A), 00012, FPD) /* FRDS RT<-single(RA) */
++APUOP(M_FSCRRD, RR, 0x398, "fscrrd", _A1(A_T), 00002, FPD) /* FSCRRD RT<-FP_status */
++APUOP(M_FSCRWR, RR, 0x3ba, "fscrwr", _A2(A_T,A_A), 00010, FP7) /* FSCRWR FP_status<-RA */
++APUOP(M_FSCRWR2, RR, 0x3ba, "fscrwr", _A1(A_A), 00010, FP7) /* FSCRWR FP_status<-RA */
++APUOP(M_CLZ, RR, 0x2a5, "clz", _A2(A_T,A_A), 00012, FX2) /* CLZ RT<-clz(RA) */
++APUOP(M_CNTB, RR, 0x2b4, "cntb", _A2(A_T,A_A), 00012, FXB) /* CNT RT<-pop(RA) */
++APUOP(M_XSBH, RR, 0x2b6, "xsbh", _A2(A_T,A_A), 00012, FX2) /* eXtSignBtoH RT<-sign_ext(RA) */
++APUOP(M_XSHW, RR, 0x2ae, "xshw", _A2(A_T,A_A), 00012, FX2) /* eXtSignHtoW RT<-sign_ext(RA) */
++APUOP(M_XSWD, RR, 0x2a6, "xswd", _A2(A_T,A_A), 00012, FX2) /* eXtSignWtoD RT<-sign_ext(RA) */
++APUOP(M_ROTI, RI7, 0x078, "roti", _A3(A_T,A_A,A_S7N), 00012, FX3) /* ROT%I RT<-RA<<<I7 */
++APUOP(M_ROTMI, RI7, 0x079, "rotmi", _A3(A_T,A_A,A_S7), 00012, FX3) /* ROT%MI RT<-RA<<I7 */
++APUOP(M_ROTMAI, RI7, 0x07a, "rotmai", _A3(A_T,A_A,A_S7), 00012, FX3) /* ROTMA%I RT<-RA<<I7 */
++APUOP(M_SHLI, RI7, 0x07b, "shli", _A3(A_T,A_A,A_U6), 00012, FX3) /* SHL%I RT<-RA<<I7 */
++APUOP(M_ROTHI, RI7, 0x07c, "rothi", _A3(A_T,A_A,A_S7N), 00012, FX3) /* ROT%I RT<-RA<<<I7 */
++APUOP(M_ROTHMI, RI7, 0x07d, "rothmi", _A3(A_T,A_A,A_S6), 00012, FX3) /* ROT%MI RT<-RA<<I7 */
++APUOP(M_ROTMAHI, RI7, 0x07e, "rotmahi", _A3(A_T,A_A,A_S6), 00012, FX3) /* ROTMA%I RT<-RA<<I7 */
++APUOP(M_SHLHI, RI7, 0x07f, "shlhi", _A3(A_T,A_A,A_U5), 00012, FX3) /* SHL%I RT<-RA<<I7 */
++APUOP(M_A, RR, 0x0c0, "a", _A3(A_T,A_A,A_B), 00112, FX2) /* Add% RT<-RA+RB */
++APUOP(M_AH, RR, 0x0c8, "ah", _A3(A_T,A_A,A_B), 00112, FX2) /* Add% RT<-RA+RB */
++APUOP(M_SF, RR, 0x040, "sf", _A3(A_T,A_A,A_B), 00112, FX2) /* SubFrom% RT<-RB-RA */
++APUOP(M_SFH, RR, 0x048, "sfh", _A3(A_T,A_A,A_B), 00112, FX2) /* SubFrom% RT<-RB-RA */
++APUOP(M_CGT, RR, 0x240, "cgt", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
++APUOP(M_CGTB, RR, 0x250, "cgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
++APUOP(M_CGTH, RR, 0x248, "cgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
++APUOP(M_CLGT, RR, 0x2c0, "clgt", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
++APUOP(M_CLGTB, RR, 0x2d0, "clgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
++APUOP(M_CLGTH, RR, 0x2c8, "clgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
++APUOP(M_CEQ, RR, 0x3c0, "ceq", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
++APUOP(M_CEQB, RR, 0x3d0, "ceqb", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
++APUOP(M_CEQH, RR, 0x3c8, "ceqh", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
++APUOP(M_HGT, RR, 0x258, "hgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */
++APUOP(M_HGT2, RR, 0x258, "hgt", _A2(A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */
++APUOP(M_HLGT, RR, 0x2d8, "hlgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */
++APUOP(M_HLGT2, RR, 0x2d8, "hlgt", _A2(A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */
++APUOP(M_HEQ, RR, 0x3d8, "heq", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */
++APUOP(M_HEQ2, RR, 0x3d8, "heq", _A2(A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */
++APUOP(M_FCEQ, RR, 0x3c2, "fceq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCEQ RT<-(RA=RB) */
++APUOP(M_FCMEQ, RR, 0x3ca, "fcmeq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCMEQ RT<-(|RA|=|RB|) */
++APUOP(M_FCGT, RR, 0x2c2, "fcgt", _A3(A_T,A_A,A_B), 00112, FX2) /* FCGT RT<-(RA<RB) */
++APUOP(M_FCMGT, RR, 0x2ca, "fcmgt", _A3(A_T,A_A,A_B), 00112, FX2) /* FCMGT RT<-(|RA|<|RB|) */
++APUOP(M_AND, RR, 0x0c1, "and", _A3(A_T,A_A,A_B), 00112, FX2) /* AND RT<-RA&RB */
++APUOP(M_NAND, RR, 0x0c9, "nand", _A3(A_T,A_A,A_B), 00112, FX2) /* NAND RT<-!(RA&RB) */
++APUOP(M_OR, RR, 0x041, "or", _A3(A_T,A_A,A_B), 00112, FX2) /* OR RT<-RA|RB */
++APUOP(M_NOR, RR, 0x049, "nor", _A3(A_T,A_A,A_B), 00112, FX2) /* NOR RT<-!(RA&RB) */
++APUOP(M_XOR, RR, 0x241, "xor", _A3(A_T,A_A,A_B), 00112, FX2) /* XOR RT<-RA^RB */
++APUOP(M_EQV, RR, 0x249, "eqv", _A3(A_T,A_A,A_B), 00112, FX2) /* EQuiValent RT<-!(RA^RB) */
++APUOP(M_ANDC, RR, 0x2c1, "andc", _A3(A_T,A_A,A_B), 00112, FX2) /* ANDComplement RT<-RA&!RB */
++APUOP(M_ORC, RR, 0x2c9, "orc", _A3(A_T,A_A,A_B), 00112, FX2) /* ORComplement RT<-RA|!RB */
++APUOP(M_ABSDB, RR, 0x053, "absdb", _A3(A_T,A_A,A_B), 00112, FXB) /* ABSoluteDiff RT<-|RA-RB| */
++APUOP(M_AVGB, RR, 0x0d3, "avgb", _A3(A_T,A_A,A_B), 00112, FXB) /* AVG% RT<-(RA+RB+1)/2 */
++APUOP(M_SUMB, RR, 0x253, "sumb", _A3(A_T,A_A,A_B), 00112, FXB) /* SUM% RT<-f(RA,RB) */
++APUOP(M_DFA, RR, 0x2cc, "dfa", _A3(A_T,A_A,A_B), 00112, FPD) /* DFAdd RT<-RA+RB */
++APUOP(M_DFM, RR, 0x2ce, "dfm", _A3(A_T,A_A,A_B), 00112, FPD) /* DFMul RT<-RA*RB */
++APUOP(M_DFS, RR, 0x2cd, "dfs", _A3(A_T,A_A,A_B), 00112, FPD) /* DFSub RT<-RA-RB */
++APUOP(M_FA, RR, 0x2c4, "fa", _A3(A_T,A_A,A_B), 00112, FP6) /* FAdd RT<-RA+RB */
++APUOP(M_FM, RR, 0x2c6, "fm", _A3(A_T,A_A,A_B), 00112, FP6) /* FMul RT<-RA*RB */
++APUOP(M_FS, RR, 0x2c5, "fs", _A3(A_T,A_A,A_B), 00112, FP6) /* FSub RT<-RA-RB */
++APUOP(M_MPY, RR, 0x3c4, "mpy", _A3(A_T,A_A,A_B), 00112, FP7) /* MPY RT<-RA*RB */
++APUOP(M_MPYH, RR, 0x3c5, "mpyh", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYH RT<-(RAh*RB)<<16 */
++APUOP(M_MPYHH, RR, 0x3c6, "mpyhh", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYHH RT<-RAh*RBh */
++APUOP(M_MPYHHU, RR, 0x3ce, "mpyhhu", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYHHU RT<-RAh*RBh */
++APUOP(M_MPYS, RR, 0x3c7, "mpys", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYS RT<-(RA*RB)>>16 */
++APUOP(M_MPYU, RR, 0x3cc, "mpyu", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYU RT<-RA*RB */
++APUOP(M_FI, RR, 0x3d4, "fi", _A3(A_T,A_A,A_B), 00112, FP7) /* FInterpolate RT<-f(RA,RB) */
++APUOP(M_ROT, RR, 0x058, "rot", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT% RT<-RA<<<RB */
++APUOP(M_ROTM, RR, 0x059, "rotm", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT%M RT<-RA<<Rb */
++APUOP(M_ROTMA, RR, 0x05a, "rotma", _A3(A_T,A_A,A_B), 00112, FX3) /* ROTMA% RT<-RA<<Rb */
++APUOP(M_SHL, RR, 0x05b, "shl", _A3(A_T,A_A,A_B), 00112, FX3) /* SHL% RT<-RA<<Rb */
++APUOP(M_ROTH, RR, 0x05c, "roth", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT% RT<-RA<<<RB */
++APUOP(M_ROTHM, RR, 0x05d, "rothm", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT%M RT<-RA<<Rb */
++APUOP(M_ROTMAH, RR, 0x05e, "rotmah", _A3(A_T,A_A,A_B), 00112, FX3) /* ROTMA% RT<-RA<<Rb */
++APUOP(M_SHLH, RR, 0x05f, "shlh", _A3(A_T,A_A,A_B), 00112, FX3) /* SHL% RT<-RA<<Rb */
++APUOP(M_MPYHHA, RR, 0x346, "mpyhha", _A3(A_T,A_A,A_B), 00113, FP7) /* MPYHHA RT<-RAh*RBh+RT */
++APUOP(M_MPYHHAU, RR, 0x34e, "mpyhhau", _A3(A_T,A_A,A_B), 00113, FP7) /* MPYHHAU RT<-RAh*RBh+RT */
++APUOP(M_DFMA, RR, 0x35c, "dfma", _A3(A_T,A_A,A_B), 00113, FPD) /* DFMAdd RT<-RT+RA*RB */
++APUOP(M_DFMS, RR, 0x35d, "dfms", _A3(A_T,A_A,A_B), 00113, FPD) /* DFMSub RT<-RA*RB-RT */
++APUOP(M_DFNMS, RR, 0x35e, "dfnms", _A3(A_T,A_A,A_B), 00113, FPD) /* DFNMSub RT<-RT-RA*RB */
++APUOP(M_DFNMA, RR, 0x35f, "dfnma", _A3(A_T,A_A,A_B), 00113, FPD) /* DFNMAdd RT<-(-RT)-RA*RB */
++APUOP(M_FMA, RRR, 0x700, "fma", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FMAdd RC<-RT+RA*RB */
++APUOP(M_FMS, RRR, 0x780, "fms", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FMSub RC<-RA*RB-RT */
++APUOP(M_FNMS, RRR, 0x680, "fnms", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FNMSub RC<-RT-RA*RB */
++APUOP(M_MPYA, RRR, 0x600, "mpya", _A4(A_C,A_A,A_B,A_T), 02111, FP7) /* MPYA RC<-RA*RB+RT */
++APUOP(M_SELB, RRR, 0x400, "selb", _A4(A_C,A_A,A_B,A_T), 02111, FX2) /* SELectBits RC<-RA&RT|RB&!RT */
++/* for system function call, this uses op-code of mtspr */
++APUOP(M_SYSCALL, RI7, 0x10c, "syscall", _A3(A_T,A_A,A_S7N), 00002, SPR) /* System Call */
++/*
++pseudo instruction:
++system call
++value of I9 operation
++0 halt
++1 rt[0] = open(MEM[ra[0]], ra[1])
++2 rt[0] = close(ra[0])
++3 rt[0] = read(ra[0], MEM[ra[1]], ra[2])
++4 rt[0] = write(ra[0], MEM[ra[1]], ra[2])
++5 printf(MEM[ra[0]], ra[1], ra[2], ra[3])
++42 rt[0] = clock()
++52 rt[0] = lseek(ra0, ra1, ra2)
++
++*/
++
++
++/* new multiprecision add/sub */
++APUOP(M_ADDX, RR, 0x340, "addx", _A3(A_T,A_A,A_B), 00113, FX2) /* Add_eXtended RT<-RA+RB+RT */
++APUOP(M_CG, RR, 0x0c2, "cg", _A3(A_T,A_A,A_B), 00112, FX2) /* CarryGenerate RT<-cout(RA+RB) */
++APUOP(M_CGX, RR, 0x342, "cgx", _A3(A_T,A_A,A_B), 00113, FX2) /* CarryGen_eXtd RT<-cout(RA+RB+RT) */
++APUOP(M_SFX, RR, 0x341, "sfx", _A3(A_T,A_A,A_B), 00113, FX2) /* Add_eXtended RT<-RA+RB+RT */
++APUOP(M_BG, RR, 0x042, "bg", _A3(A_T,A_A,A_B), 00112, FX2) /* CarryGenerate RT<-cout(RA+RB) */
++APUOP(M_BGX, RR, 0x343, "bgx", _A3(A_T,A_A,A_B), 00113, FX2) /* CarryGen_eXtd RT<-cout(RA+RB+RT) */
++
++/*
++
++The following ops are a subset of above except with feature bits set.
++Feature bits are bits 11-17 of the instruction:
++
++ 11 - C & P feature bit
++ 12 - disable interrupts
++ 13 - enable interrupts
++
++*/
++APUOPFB(M_BID, RR, 0x1a8, 0x20, "bid", _A1(A_A), 00010, BR) /* BI IP<-RA */
++APUOPFB(M_BIE, RR, 0x1a8, 0x10, "bie", _A1(A_A), 00010, BR) /* BI IP<-RA */
++APUOPFB(M_BISLD, RR, 0x1a9, 0x20, "bisld", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
++APUOPFB(M_BISLE, RR, 0x1a9, 0x10, "bisle", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
++APUOPFB(M_IRETD, RR, 0x1aa, 0x20, "iretd", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
++APUOPFB(M_IRETD2, RR, 0x1aa, 0x20, "iretd", _A0(), 00010, BR) /* IRET IP<-SRR0 */
++APUOPFB(M_IRETE, RR, 0x1aa, 0x10, "irete", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
++APUOPFB(M_IRETE2, RR, 0x1aa, 0x10, "irete", _A0(), 00010, BR) /* IRET IP<-SRR0 */
++APUOPFB(M_BISLEDD, RR, 0x1ab, 0x20, "bisledd", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
++APUOPFB(M_BISLEDE, RR, 0x1ab, 0x10, "bislede", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
++APUOPFB(M_BIHNZD, RR, 0x12b, 0x20, "bihnzd", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
++APUOPFB(M_BIHNZE, RR, 0x12b, 0x10, "bihnze", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
++APUOPFB(M_BIHZD, RR, 0x12a, 0x20, "bihzd", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
++APUOPFB(M_BIHZE, RR, 0x12a, 0x10, "bihze", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
++APUOPFB(M_BINZD, RR, 0x129, 0x20, "binzd", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
++APUOPFB(M_BINZE, RR, 0x129, 0x10, "binze", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
++APUOPFB(M_BIZD, RR, 0x128, 0x20, "bizd", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
++APUOPFB(M_BIZE, RR, 0x128, 0x10, "bize", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
++APUOPFB(M_SYNCC, RR, 0x002, 0x40, "syncc", _A0(), 00000, BR) /* SYNCC flush_pipe */
++APUOPFB(M_HBRP, LBTI, 0x1ac, 0x40, "hbrp", _A0(), 00010, LS) /* HBR BTB[B9]<-M[Ra] */
++
++/* Synonyms required by the AS manual. */
++APUOP(M_LR, RI10, 0x020, "lr", _A2(A_T,A_A), 00012, FX2) /* OR%I RT<-RA|I10 */
++APUOP(M_BIHT, RR, 0x12b, "biht", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
++APUOP(M_BIHF, RR, 0x12a, "bihf", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
++APUOP(M_BIT, RR, 0x129, "bit", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
++APUOP(M_BIF, RR, 0x128, "bif", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
++APUOPFB(M_BIHTD, RR, 0x12b, 0x20, "bihtd", _A2(A_T,A_A), 00011, BR) /* BIHNF IP<-RA_if(RT) */
++APUOPFB(M_BIHTE, RR, 0x12b, 0x10, "bihte", _A2(A_T,A_A), 00011, BR) /* BIHNF IP<-RA_if(RT) */
++APUOPFB(M_BIHFD, RR, 0x12a, 0x20, "bihfd", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
++APUOPFB(M_BIHFE, RR, 0x12a, 0x10, "bihfe", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
++APUOPFB(M_BITD, RR, 0x129, 0x20, "bitd", _A2(A_T,A_A), 00011, BR) /* BINF IP<-RA_if(RT) */
++APUOPFB(M_BITE, RR, 0x129, 0x10, "bite", _A2(A_T,A_A), 00011, BR) /* BINF IP<-RA_if(RT) */
++APUOPFB(M_BIFD, RR, 0x128, 0x20, "bifd", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
++APUOPFB(M_BIFE, RR, 0x128, 0x10, "bife", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
++
++#undef _A0
++#undef _A1
++#undef _A2
++#undef _A3
++#undef _A4
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/include/opcode/spu.h binutils/include/opcode/spu.h
+--- binutils-2.16.1/include/opcode/spu.h 1970-01-01 01:00:00.000000000 +0100
++++ binutils/include/opcode/spu.h 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,128 @@
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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. */
++
++
++/* These two enums are from rel_apu/common/spu_asm_format.h */
++/* definition of instruction format */
++typedef enum {
++ RRR,
++ RI18,
++ RI16,
++ RI10,
++ RI8,
++ RI7,
++ RR,
++ LBT,
++ LBTI,
++ IDATA,
++ UNKNOWN_IFORMAT
++} spu_iformat;
++
++/* These values describe assembly instruction arguments. They indicate
++ * how to encode, range checking and which relocation to use. */
++typedef enum {
++ A_T, /* register at pos 0 */
++ A_A, /* register at pos 7 */
++ A_B, /* register at pos 14 */
++ A_C, /* register at pos 21 */
++ A_S, /* special purpose register at pos 7 */
++ A_H, /* channel register at pos 7 */
++ A_P, /* parenthesis, this has to separate regs from immediates */
++ A_S3,
++ A_S6,
++ A_S7N,
++ A_S7,
++ A_U7A,
++ A_U7B,
++ A_S10B,
++ A_S10,
++ A_S11,
++ A_S11I,
++ A_S14,
++ A_S16,
++ A_S18,
++ A_R18,
++ A_U3,
++ A_U5,
++ A_U6,
++ A_U7,
++ A_U14,
++ A_X16,
++ A_U18,
++ A_MAX
++} spu_aformat;
++
++enum spu_insns {
++#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
++ TAG,
++#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
++ TAG,
++#include "opcode/spu-insns.h"
++#undef APUOP
++#undef APUOPFB
++ M_SPU_MAX
++};
++
++struct spu_opcode
++{
++ spu_iformat insn_type;
++ unsigned int opcode;
++ char *mnemonic;
++ int arg[5];
++};
++
++#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size))
++#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1))
++
++#define DECODE_INSN_RT(insn) (insn & 0x7f)
++#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
++#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
++#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
++
++#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14)
++#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14)
++
++/* For branching, immediate loads, hbr and lqa/stqa. */
++#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7)
++#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7)
++
++/* for stop */
++#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0)
++
++/* For ila */
++#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7)
++#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7)
++
++/* For rotate and shift and generate control mask */
++#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14)
++#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14)
++
++/* For float <-> int conversion */
++#define DECODE_INSN_I8(insn) SIGNED_EXTRACT(insn,8,14)
++#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14)
++
++/* For hbr */
++#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
++#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
++#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
++#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
++
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/Makefile.am binutils/ld/Makefile.am
+--- binutils-2.16.1/ld/Makefile.am 2005-01-20 20:37:49.000000000 +0100
++++ binutils/ld/Makefile.am 2006-03-30 01:23:21.000000000 +0200
+@@ -151,6 +151,7 @@
+ eelf32_i860.o \
+ eelf32_sparc.o \
+ eelf32_sparc_vxworks.o \
++ eelf32_spu.o \
+ eelf32b4300.o \
+ eelf32bfin.o \
+ eelf32bfinfd.o \
+@@ -373,6 +374,7 @@
+ ez8002.o
+
+ ALL_64_EMULATIONS = \
++ eelf64_lv2.o \
+ eelf64_aix.o \
+ eelf64_ia64.o \
+ eelf64_ia64_fbsd.o \
+@@ -654,6 +656,9 @@
+ $(srcdir)/emultempl/vxworks.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32_sparc_vxworks "$(tdir_elf32_sparc_vxworks)"
++eelf32_spu.c: $(srcdir)/emulparams/elf32_spu.sh \
++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
++ ${GENSCRIPTS} elf32_spu "$(tdir_elf32_spu)"
+ eelf32_i860.c: $(srcdir)/emulparams/elf32_i860.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf32_i860 "$(tdir_elf32_i860)"
+@@ -797,6 +802,9 @@
+ $(srcdir)/emulparams/hppa64linux.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf64hppa "$(tdir_elf64hppa)"
++eelf64_lv2.c: $(srcdir)/emulparams/elf64_lv2.sh \
++ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
++ ${GENSCRIPTS} elf64_lv2 "$(tdir_elf64_aix)"
+ eelf64_aix.c: $(srcdir)/emulparams/elf64_aix.sh \
+ $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} elf64_aix "$(tdir_elf64_aix)"
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/configure.tgt binutils/ld/configure.tgt
+--- binutils-2.16.1/ld/configure.tgt 2005-02-08 20:54:27.000000000 +0100
++++ binutils/ld/configure.tgt 2006-03-30 01:23:21.000000000 +0200
+@@ -374,14 +374,14 @@
+ tdir_elf32ppcsim=`echo ${targ_alias} | sed -e 's/ppc/ppcsim/'` ;;
+ powerpc*-*-linux*) case "${targ}" in
+ *64*) targ_emul=elf64ppc
+- targ_extra_emuls="elf32ppclinux elf32ppc elf32ppcsim"
++ targ_extra_emuls="elf32ppclinux elf32ppc elf32ppcsim elf32_spu"
+ targ_extra_libpath="elf32ppclinux elf32ppc"
+ tdir_elf32ppc=`echo "${targ_alias}" | sed -e 's/64//'`
+ tdir_elf32ppclinux=$tdir_elf32ppc
+ tdir_elf32ppcsim=$tdir_elf32ppc
+ ;;
+ *) targ_emul=elf32ppclinux
+- targ_extra_emuls="elf32ppc elf32ppcsim"
++ targ_extra_emuls="elf32ppc elf32ppcsim elf32_spu"
+ targ_extra_libpath=elf32ppc
+ if test "${want64}" = "true"; then
+ targ_extra_emuls="$targ_extra_emuls elf64ppc"
+@@ -427,6 +427,7 @@
+ powerpc-*-beos*) targ_emul=aixppc ;;
+ powerpc-*-windiss*) targ_emul=elf32ppcwindiss ;;
+ powerpc-*-lynxos*) targ_emul=ppclynx ;;
++ppu-*-lv2) targ_emul=elf64_lv2 targ_extra_emuls="elf32_spu" ;;
+ rs6000-*-aix5*) targ_emul=aix5rs6 ;;
+ rs6000-*-aix*) targ_emul=aixrs6
+ ;;
+@@ -536,6 +537,9 @@
+ sparc*-wrs-vxworks*) targ_emul=sparcaout ;;
+ sparc*-*-rtems*) targ_emul=elf32_sparc
+ ;;
++spu-*-lv2) targ_emul=elf32_spu ;;
++spu-*-elf*) targ_emul=elf32_spu
++ ;;
+ tic30-*-*aout*) targ_emul=tic30aout ;;
+ tic30-*-*coff*) targ_emul=tic30coff ;;
+ tic4x-*-* | c4x-*-*) targ_emul=tic4xcoff ; targ_extra_emuls="tic3xcoff tic3xcoff_onchip" ;;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/emulparams/elf32_spu.sh binutils/ld/emulparams/elf32_spu.sh
+--- binutils-2.16.1/ld/emulparams/elf32_spu.sh 1970-01-01 01:00:00.000000000 +0100
++++ binutils/ld/emulparams/elf32_spu.sh 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,14 @@
++SCRIPT_NAME=elf
++TEMPLATE_NAME=elf32
++OUTPUT_FORMAT="elf32-spu"
++ARCH=spu
++MACHINE=
++TEXT_START_ADDR=0x0000080
++ALIGNMENT=16
++OTHER_END_SYMBOLS='PROVIDE (__stack = 0x3fff0);'
++NO_SMALL_DATA=true
++EMBEDDED=true
++MAXPAGESIZE=0x80
++DATA_ADDR="ALIGN(${MAXPAGESIZE})"
++GENERATE_SHLIB_SCRIPT=yes
++OTHER_GOT_SECTIONS=".toe ALIGN(128) : { *(.toe) } = 0"
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/emulparams/elf64_lv2.sh binutils/ld/emulparams/elf64_lv2.sh
+--- binutils-2.16.1/ld/emulparams/elf64_lv2.sh 1970-01-01 01:00:00.000000000 +0100
++++ binutils/ld/emulparams/elf64_lv2.sh 2004-10-26 06:22:56.000000000 +0200
+@@ -0,0 +1,51 @@
++TEMPLATE_NAME=elf32
++EXTRA_EM_FILE=ppc64elf
++ELFSIZE=64
++GENERATE_SHLIB_SCRIPT=yes
++GENERATE_PIE_SCRIPT=yes
++SCRIPT_NAME=elf
++OUTPUT_FORMAT="elf64-powerpc"
++TEXT_START_ADDR=0x10000
++#SEGMENT_SIZE=0x10000000
++MAXPAGESIZE=0x10000
++COMMONPAGESIZE=0x1000
++ARCH=powerpc:common64
++MACHINE=
++NOP=0x60000000
++EXECUTABLE_SYMBOLS='PROVIDE (__stack = 0); PROVIDE (___stack = 0);'
++OTHER_BSS_END_SYMBOLS='__end = .;'
++CTOR_START='PROVIDE (__CTOR_LIST__ = .); PROVIDE (___CTOR_LIST__ = .);'
++CTOR_END='PROVIDE (__CTOR_END__ = .); PROVIDE (___CTOR_END__ = .);'
++DTOR_START='PROVIDE (__DTOR_LIST__ = .); PROVIDE (___DTOR_LIST__ = .);'
++DTOR_END='PROVIDE (__DTOR_END__ = .); PROVIDE (___DTOR_END__ = .);'
++OTHER_TEXT_SECTIONS="*(.sfpr .glink)"
++BSS_PLT=
++OTHER_BSS_SYMBOLS="
++ .tocbss ${RELOCATING-0}${RELOCATING+ALIGN(8)} : { *(.tocbss)}"
++OTHER_PLT_RELOC_SECTIONS="
++ .rela.tocbss ${RELOCATING-0} : { *(.rela.tocbss) }"
++
++if test x${RELOCATING+set} = xset; then
++ GOT="
++ .got ALIGN(8) : { *(.got .toc) }"
++else
++ GOT="
++ .got 0 : { *(.got) }
++ .toc 0 : { *(.toc) }"
++fi
++OTHER_GOT_RELOC_SECTIONS="
++ .rela.toc ${RELOCATING-0} : { *(.rela.toc) }"
++OTHER_READWRITE_SECTIONS="
++ .toc1 ${RELOCATING-0}${RELOCATING+ALIGN(8)} : { *(.toc1) }
++ .opd ${RELOCATING-0}${RELOCATING+ALIGN(8)} : { KEEP (*(.opd)) }"
++
++# Treat a host that matches the target with the possible exception of "64"
++# in the name as if it were native.
++if test `echo "$host" | sed -e s/64//` = `echo "$target" | sed -e s/64//`; then
++ case " $EMULATION_LIBPATH " in
++ *" ${EMULATION_NAME} "*)
++ NATIVE=yes
++ ;;
++ esac
++fi
++
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/emulparams/elf64ppc.sh binutils/ld/emulparams/elf64ppc.sh
+--- binutils-2.16.1/ld/emulparams/elf64ppc.sh 2003-07-28 05:33:48.000000000 +0200
++++ binutils/ld/emulparams/elf64ppc.sh 2006-03-30 01:23:21.000000000 +0200
+@@ -12,6 +12,12 @@
+ ARCH=powerpc:common64
+ MACHINE=
+ NOP=0x60000000
++#EXECUTABLE_SYMBOLS='PROVIDE (__stack = 0); PROVIDE (___stack = 0);'
++#OTHER_BSS_END_SYMBOLS='__end = .;'
++#CTOR_START='PROVIDE (__CTOR_LIST__ = .); PROVIDE (___CTOR_LIST__ = .);'
++#CTOR_END='PROVIDE (__CTOR_END__ = .); PROVIDE (___CTOR_END__ = .);'
++#DTOR_START='PROVIDE (__DTOR_LIST__ = .); PROVIDE (___DTOR_LIST__ = .);'
++#DTOR_END='PROVIDE (__DTOR_END__ = .); PROVIDE (___DTOR_END__ = .);'
+ OTHER_TEXT_SECTIONS="*(.sfpr .glink)"
+ BSS_PLT=
+ OTHER_BSS_SYMBOLS="
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/emultempl/elf32.em binutils/ld/emultempl/elf32.em
+--- binutils-2.16.1/ld/emultempl/elf32.em 2005-04-13 19:59:07.000000000 +0200
++++ binutils/ld/emultempl/elf32.em 2006-03-30 01:23:21.000000000 +0200
+@@ -243,9 +243,16 @@
+ meaningful inode numbers will never set st_ino to zero, this is
+ merely an optimization, so we do not need to worry about false
+ negatives. */
++#ifndef __MINGW32__
+ if (st.st_dev == global_stat.st_dev
+ && st.st_ino == global_stat.st_ino
+ && st.st_ino != 0)
++#else
++ if (st.st_dev == global_stat.st_dev
++ && st.st_ino == global_stat.st_ino
++ && st.st_size == global_stat.st_size
++ && strcmp (lbasename(s->the_bfd->filename), global_needed->name) != 0 )
++#endif
+ {
+ global_found = TRUE;
+ return;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/ld.texinfo binutils/ld/ld.texinfo
+--- binutils-2.16.1/ld/ld.texinfo 2005-06-12 20:35:45.000000000 +0200
++++ binutils/ld/ld.texinfo 2006-03-30 01:23:21.000000000 +0200
+@@ -1834,6 +1834,14 @@
+ symbols from, to ensure that they get linked in, just like a normal
+ object file).
+
++The @option{-shared} option creates a relocatable DLL. To convert a
++relocatable DLL to a non-relocatable one, strip the @code{.reloc} section
++using
++
++@smallexample
++strip -R .reloc @var{foo.dll}
++@end smallexample
++
+ In addition to the options common to all targets, the i386 PE linker
+ support additional command line options that are specific to the i386
+ PE target. Options that take values may be separated from their
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/ldgram.y binutils/ld/ldgram.y
+--- binutils-2.16.1/ld/ldgram.y 2005-01-21 13:04:25.000000000 +0100
++++ binutils/ld/ldgram.y 2006-03-30 01:23:21.000000000 +0200
+@@ -1079,6 +1079,11 @@
+ $$ = exp_intop (i);
+ break;
+ }
++#if (defined(BPA))
++ if (strcmp(s, "PT_SPU_INFO") == 0)
++ $$ = exp_intop(0x70000000);
++#endif
++
+ if (i == sizeof phdr_types / sizeof phdr_types[0])
+ {
+ if (strcmp (s, "PT_GNU_EH_FRAME") == 0)
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/ldmain.c binutils/ld/ldmain.c
+--- binutils-2.16.1/ld/ldmain.c 2005-03-03 12:51:58.000000000 +0100
++++ binutils/ld/ldmain.c 2006-03-30 01:23:21.000000000 +0200
+@@ -313,6 +324,10 @@
+ link_info.need_relax_finalize = FALSE;
+ link_info.warn_shared_textrel = FALSE;
+
++#if defined(BPA)
++ link_info.spuplugin = FALSE;
++#endif
++
+ ldfile_add_arch ("");
+
+ config.make_executable = TRUE;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/lexsup.c binutils/ld/lexsup.c
+--- binutils-2.16.1/ld/lexsup.c 2005-03-03 12:52:00.000000000 +0100
++++ binutils/ld/lexsup.c 2006-03-30 01:23:21.000000000 +0200
+@@ -153,6 +153,11 @@
+ OPTION_ERROR_UNRESOLVED_SYMBOLS,
+ OPTION_WARN_SHARED_TEXTREL,
+ OPTION_REDUCE_MEMORY_OVERHEADS
++/* CELL LOCAL Begin */
++#if defined(BPA)
++ , OPTION_SPUPLUGIN
++#endif
++/* CELL LOCAL End */
+ };
+
+ /* The long options. This structure is used for both the option
+@@ -518,6 +523,10 @@
+ TWO_DASHES },
+ { {"wrap", required_argument, NULL, OPTION_WRAP},
+ '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES },
++#if defined(BPA)
++ { {"plugin", no_argument, NULL, OPTION_SPUPLUGIN},
++ '\0', NULL, N_("Make SPU Plugin"), ONE_DASH },
++#endif
+ };
+
+ #define OPTION_COUNT ARRAY_SIZE (ld_options)
+@@ -1329,6 +1338,12 @@
+ link_info.fini_function = optarg;
+ break;
+
++#if defined(BPA)
++ case OPTION_SPUPLUGIN:
++ link_info.spuplugin = TRUE;
++ break;
++#endif
++
+ case OPTION_REDUCE_MEMORY_OVERHEADS:
+ command_line.reduce_memory_overheads = TRUE;
+ if (config.hash_table_size == 0)
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/scripttempl/elf.sc binutils/ld/scripttempl/elf.sc
+--- binutils-2.16.1/ld/scripttempl/elf.sc 2005-03-22 16:32:43.000000000 +0100
++++ binutils/ld/scripttempl/elf.sc 2006-03-30 01:23:21.000000000 +0200
+@@ -301,6 +301,7 @@
+ ${RELOCATING+${TEXT_START_SYMBOLS}}
+ *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
+ KEEP (*(.text.*personality*))
++ *(.spu.elf)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ ${RELOCATING+${OTHER_TEXT_SECTIONS}}
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/ld/scripttempl/pe.sc binutils/ld/scripttempl/pe.sc
+--- binutils-2.16.1/ld/scripttempl/pe.sc 2004-12-01 00:54:53.000000000 +0100
++++ binutils/ld/scripttempl/pe.sc 2006-03-30 01:23:21.000000000 +0200
+@@ -65,10 +65,20 @@
+ ${R_TEXT}
+ *(.glue_7t)
+ *(.glue_7)
+- ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+- LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); }
+- ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+- LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); }
++ ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
++ LONG (-1);
++ *(EXCLUDE_FILE (*crtend.o) .ctors);
++ *(.ctor);
++ *(SORT(.ctors.*));
++ *crtend.o (.ctors);
++ LONG (0); }
++ ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
++ LONG (-1);
++ *(EXCLUDE_FILE (*crtend.o) .dtors);
++ *(.dtor);
++ *(SORT(.dtors.*));
++ *crtend.o (.dtors);
++ LONG (0); }
+ ${RELOCATING+ *(.fini)}
+ /* ??? Why is .gcc_exc here? */
+ ${RELOCATING+ *(.gcc_exc)}
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/Makefile.am binutils/opcodes/Makefile.am
+--- binutils-2.16.1/opcodes/Makefile.am 2005-02-21 12:48:33.000000000 +0100
++++ binutils/opcodes/Makefile.am 2006-03-30 01:23:21.000000000 +0200
+@@ -149,6 +149,8 @@
+ sh64-opc.c \
+ sparc-dis.c \
+ sparc-opc.c \
++ spu-dis.c \
++ spu-opc.c \
+ tic30-dis.c \
+ tic4x-dis.c \
+ tic54x-dis.c \
+@@ -263,6 +265,8 @@
+ sh64-opc.lo \
+ sparc-dis.lo \
+ sparc-opc.lo \
++ spu-dis.lo \
++ spu-opc.lo \
+ tic30-dis.lo \
+ tic4x-dis.lo \
+ tic54x-dis.lo \
+@@ -805,6 +809,12 @@
+ $(INCDIR)/symcat.h $(INCDIR)/libiberty.h opintl.h
+ sparc-opc.lo: sparc-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/opcode/sparc.h
++spu-dis.lo: spu-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
++ $(INCDIR)/opcode/spu.h $(INCDIR)/dis-asm.h $(BFD_H) \
++ $(INCDIR)/symcat.h $(INCDIR)/libiberty.h opintl.h \
++ $(INCDIR)/opcode/spu-insns.h
++spu-opc.lo: spu-opc.c sysdep.h config.h $(INCDIR)/ansidecl.h \
++ $(INCDIR)/opcode/spu.h
+ tic30-dis.lo: tic30-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/symcat.h $(INCDIR)/opcode/tic30.h
+ tic4x-dis.lo: tic4x-dis.c $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h \
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/configure binutils/opcodes/configure
+--- binutils-2.16.1/opcodes/configure 2005-01-31 21:30:37.000000000 +0100
++++ binutils/opcodes/configure 2006-03-30 01:23:21.000000000 +0200
+@@ -8655,6 +8655,7 @@
+ done
+ ta="$ta sh-dis.lo" ;;
+ bfd_sparc_arch) ta="$ta sparc-dis.lo sparc-opc.lo" ;;
++ bfd_spu_arch) ta="$ta spu-dis.lo spu-opc.lo" ;;
+ bfd_tahoe_arch) ;;
+ bfd_tic30_arch) ta="$ta tic30-dis.lo" ;;
+ bfd_tic4x_arch) ta="$ta tic4x-dis.lo" ;;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/configure.in binutils/opcodes/configure.in
+--- binutils-2.16.1/opcodes/configure.in 2004-11-08 14:17:37.000000000 +0100
++++ binutils/opcodes/configure.in 2006-03-30 01:23:21.000000000 +0200
+@@ -232,6 +232,7 @@
+ done
+ ta="$ta sh-dis.lo" ;;
+ bfd_sparc_arch) ta="$ta sparc-dis.lo sparc-opc.lo" ;;
++ bfd_spu_arch) ta="$ta spu-dis.lo spu-opc.lo" ;;
+ bfd_tahoe_arch) ;;
+ bfd_tic30_arch) ta="$ta tic30-dis.lo" ;;
+ bfd_tic4x_arch) ta="$ta tic4x-dis.lo" ;;
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/disassemble.c binutils/opcodes/disassemble.c
+--- binutils-2.16.1/opcodes/disassemble.c 2005-03-03 12:49:48.000000000 +0100
++++ binutils/opcodes/disassemble.c 2006-03-30 01:23:21.000000000 +0200
+@@ -25,6 +25,7 @@
+ #define ARCH_s390
+ #define ARCH_sh
+ #define ARCH_sparc
++#define ARCH_spu
+ #define ARCH_tic30
+ #define ARCH_tic4x
+ #define ARCH_tic54x
+@@ -120,6 +121,11 @@
+ disassemble = print_insn_avr;
+ break;
+ #endif
++#ifdef ARCH_spu
++ case bfd_arch_spu:
++ disassemble = print_insn_spu;
++ break;
++#endif
+ #ifdef ARCH_cris
+ case bfd_arch_cris:
+ disassemble = cris_get_disassembler (abfd);
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/ppc-dis.c binutils/opcodes/ppc-dis.c
+--- binutils-2.16.1/opcodes/ppc-dis.c 2005-03-22 16:31:19.000000000 +0100
++++ binutils/opcodes/ppc-dis.c 2006-03-30 01:23:21.000000000 +0200
+@@ -81,6 +81,8 @@
+ dialect &= ~PPC_OPCODE_64;
+ else if (strstr (info->disassembler_options, "64") != NULL)
+ dialect |= PPC_OPCODE_64;
++ else if (strstr (info->disassembler_options, "cellppu") != NULL)
++ dialect |= PPC_OPCODE_CELLPPU;
+ }
+
+ ((struct dis_private *) &info->private_data)->dialect = dialect;
+@@ -158,6 +160,8 @@
+ int invalid;
+ int need_comma;
+ int need_paren;
++ int print_hex;
++ long hexval;
+
+ table_op = PPC_OP (opcode->opcode);
+ if (op < table_op)
+@@ -191,6 +195,7 @@
+ /* Now extract and print the operands. */
+ need_comma = 0;
+ need_paren = 0;
++ print_hex = 0;
+ for (opindex = opcode->operands; *opindex != 0; opindex++)
+ {
+ long value;
+@@ -236,12 +241,20 @@
+ else if ((operand->flags & PPC_OPERAND_VR) != 0)
+ (*info->fprintf_func) (info->stream, "v%ld", value);
+ else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
+- (*info->print_address_func) (memaddr + value, info);
++ (*info->print_address_func) (memaddr + value, info);
+ else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
+- (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
++ {
++ (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
++ print_hex = 1;
++ hexval = value & 0xffffffff;
++ }
+ else if ((operand->flags & PPC_OPERAND_CR) == 0
+ || (dialect & PPC_OPCODE_PPC) == 0)
+- (*info->fprintf_func) (info->stream, "%ld", value);
++ {
++ (*info->fprintf_func) (info->stream, "%ld", value);
++ print_hex = 1;
++ hexval = value;
++ }
+ else
+ {
+ if (operand->bits == 3)
+@@ -275,6 +288,9 @@
+ }
+ }
+
++ if (print_hex && (hexval > 16 || hexval < -1))
++ (*info->fprintf_func) (info->stream, "\t\t# %lx", hexval);
++
+ /* We have found and printed an instruction; return. */
+ return 4;
+ }
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/ppc-opc.c binutils/opcodes/ppc-opc.c
+--- binutils-2.16.1/opcodes/ppc-opc.c 2005-04-19 19:09:56.000000000 +0200
++++ binutils/opcodes/ppc-opc.c 2006-03-30 01:23:21.000000000 +0200
+@@ -560,6 +560,10 @@
+
+ };
+
++/* Version 2 of the PowerPC User ISA is compatible with POWER4.
++ Enable the POWER4 extensions by default, e.g., BO encoding. */
++#define POWER4_COMPAT(DIALECT) (((DIALECT) & PPC_OPCODE_NOPOWER4) == 0)
++
+ /* The functions used to insert and extract complicated operands. */
+
+ /* The BA field in an XL form instruction when it must be the same as
+@@ -651,7 +655,7 @@
+ int dialect,
+ const char **errmsg ATTRIBUTE_UNUSED)
+ {
+- if ((dialect & PPC_OPCODE_POWER4) == 0)
++ if (!POWER4_COMPAT (dialect))
+ {
+ if ((value & 0x8000) != 0)
+ insn |= 1 << 21;
+@@ -671,7 +675,7 @@
+ int dialect,
+ int *invalid)
+ {
+- if ((dialect & PPC_OPCODE_POWER4) == 0)
++ if (!POWER4_COMPAT (dialect))
+ {
+ if (((insn & (1 << 21)) == 0) != ((insn & (1 << 15)) == 0))
+ *invalid = 1;
+@@ -696,7 +700,7 @@
+ int dialect,
+ const char **errmsg ATTRIBUTE_UNUSED)
+ {
+- if ((dialect & PPC_OPCODE_POWER4) == 0)
++ if (!POWER4_COMPAT (dialect))
+ {
+ if ((value & 0x8000) == 0)
+ insn |= 1 << 21;
+@@ -716,7 +720,7 @@
+ int dialect,
+ int *invalid)
+ {
+- if ((dialect & PPC_OPCODE_POWER4) == 0)
++ if (!POWER4_COMPAT (dialect))
+ {
+ if (((insn & (1 << 21)) == 0) == ((insn & (1 << 15)) == 0))
+ *invalid = 1;
+@@ -736,7 +740,7 @@
+ static int
+ valid_bo (long value, int dialect)
+ {
+- if ((dialect & PPC_OPCODE_POWER4) == 0)
++ if (!POWER4_COMPAT (dialect))
+ {
+ /* Certain encodings have bits that are required to be zero.
+ These are (z must be zero, y may be anything):
+@@ -1796,6 +1800,7 @@
+ #define MFDEC2 PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE
+ #define BOOKE PPC_OPCODE_BOOKE
+ #define BOOKE64 PPC_OPCODE_BOOKE64
++#define CELLPPU PPC_OPCODE_CELLPPU
+ #define CLASSIC PPC_OPCODE_CLASSIC
+ #define PPCSPE PPC_OPCODE_SPE
+ #define PPCISEL PPC_OPCODE_ISEL
+@@ -1825,7 +1830,8 @@
+ sorted by major opcode. */
+
+ const struct powerpc_opcode powerpc_opcodes[] = {
+-{ "attn", X(0,256), X_MASK, POWER4, { 0 } },
++{ "attn", XRC(0,256,0), X_MASK, PPC64, { 0 }},
++{ "attn.", XRC(0,256,1), X_MASK, PPC64, { 0 }},
+ { "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC64, { RA, SI } },
+ { "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC64, { RA, SI } },
+ { "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC64, { RA, SI } },
+@@ -2707,7 +2713,8 @@
+ { "bcla+", B(16,1,1), B_MASK, PPCCOM, { BOE, BI, BDPA } },
+ { "bcla", B(16,1,1), B_MASK, COM, { BO, BI, BDA } },
+
+-{ "sc", SC(17,1,0), SC_MASK, PPC, { LEV } },
++{ "scv", SC(17,0,1), SC_MASK, PPC64, { LEV } },
++{ "sc", SC(17,1,0), SC_MASK, PPC, { LEV } },
+ { "svc", SC(17,0,0), SC_MASK, POWER, { SVC_LEV, FL1, FL2 } },
+ { "svcl", SC(17,0,1), SC_MASK, POWER, { SVC_LEV, FL1, FL2 } },
+ { "svca", SC(17,1,0), SC_MASK, PWRCOM, { SV } },
+@@ -2944,6 +2951,7 @@
+ { "bclrel", XLLK(19,17,1), XLBB_MASK, BOOKE64, { BO, BI } },
+
+ { "rfid", XL(19,18), 0xffffffff, PPC64, { 0 } },
++{ "hrfid", XL(19,274),0xffffffff, PPC64, { 0 } },
+
+ { "crnot", XL(19,33), XL_MASK, PPCCOM, { BT, BA, BBA } },
+ { "crnor", XL(19,33), XL_MASK, COM, { BT, BA, BB } },
+@@ -2952,6 +2960,7 @@
+ { "rfi", XL(19,50), 0xffffffff, COM, { 0 } },
+ { "rfci", XL(19,51), 0xffffffff, PPC403 | BOOKE, { 0 } },
+
++{ "rfscv", XL(19,82), 0xffffffff, PPC64, { 0 } },
+ { "rfsvc", XL(19,82), 0xffffffff, POWER, { 0 } },
+
+ { "crandc", XL(19,129), XL_MASK, COM, { BT, BA, BB } },
+@@ -3271,12 +3280,13 @@
+ { "isel", XISEL(31,15), XISEL_MASK, PPCISEL, { RT, RA, RB, CRB } },
+
+ { "mfocrf", XFXM(31,19,0,1), XFXFXM_MASK, COM, { RT, FXM } },
+-{ "mfcr", X(31,19), XRARB_MASK, NOPOWER4, { RT } },
++{ "mfcr", XFXM(31,19,0,0), XRARB_MASK, NOPOWER4, { RT } },
+ { "mfcr", X(31,19), XFXFXM_MASK, POWER4, { RT, FXM4 } },
+
+ { "lwarx", X(31,20), X_MASK, PPC, { RT, RA0, RB } },
+
+ { "ldx", X(31,21), X_MASK, PPC64, { RT, RA0, RB } },
++{ "ldbrx", X(31,532), X_MASK, PPC64, { RT, RA0, RB } },
+
+ { "icbt", X(31,22), X_MASK, BOOKE, { CT, RA, RB } },
+ { "icbt", X(31,262), XRT_MASK, PPC403, { RA, RB } },
+@@ -3433,6 +3443,7 @@
+ { "mtmsr", X(31,146), XRARB_MASK, COM, { RS } },
+
+ { "stdx", X(31,149), X_MASK, PPC64, { RS, RA0, RB } },
++{ "stdbrx", X(31,660), X_MASK, PPC64, { RS, RA0, RB } },
+
+ { "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA0, RB } },
+
+@@ -3570,7 +3581,7 @@
+ { "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB } },
+ { "lscbx.", XRC(31,277,1), X_MASK, M601, { RT, RA, RB } },
+
+-{ "dcbt", X(31,278), X_MASK, PPC, { CT, RA, RB } },
++{ "dcbt", X(31,278), X_MASK, PPC, { CT, RA, RB } },
+
+ { "lhzx", X(31,279), X_MASK, COM, { RT, RA0, RB } },
+
+@@ -3827,6 +3838,7 @@
+ { "mfthrm3", XSPR(31,339,1022), XSPR_MASK, PPC750, { RT } },
+ { "mfpbu2", XSPR(31,339,1023), XSPR_MASK, PPC403, { RT } },
+ { "mfspr", X(31,339), X_MASK, COM, { RT, SPR } },
++{ "mfctrl", X(31,339), XSPR_MASK, PPC64, { RT } },
+
+ { "lwax", X(31,341), X_MASK, PPC64, { RT, RA0, RB } },
+
+@@ -4109,6 +4121,7 @@
+ { "mtthrm3", XSPR(31,467,1022), XSPR_MASK, PPC750, { RS } },
+ { "mtpbu2", XSPR(31,467,1023), XSPR_MASK, PPC403, { RS } },
+ { "mtspr", X(31,467), X_MASK, COM, { SPR, RS } },
++{ "mtctrl", X(31,467), XSPR_MASK, PPC64, { RS } },
+
+ { "dcbi", X(31,470), XRT_MASK, PPC, { RA, RB } },
+
+@@ -4613,6 +4626,15 @@
+ { "fcfid", XRC(63,846,0), XRA_MASK, PPC64, { FRT, FRB } },
+ { "fcfid.", XRC(63,846,1), XRA_MASK, PPC64, { FRT, FRB } },
+
++{ "cctpl", 0x7c210b78, 0xffffffff, CELLPPU, { 0 }},
++{ "cctpm", 0x7c421378, 0xffffffff, CELLPPU, { 0 }},
++{ "cctph", 0x7c631b78, 0xffffffff, CELLPPU, { 0 }},
++{ "db8cyc", 0x7f9ce378, 0xffffffff, CELLPPU, { 0 }},
++{ "db10cyc", 0x7fbdeb78, 0xffffffff, CELLPPU, { 0 }},
++{ "db12cyc", 0x7fdef378, 0xffffffff, CELLPPU, { 0 }},
++{ "db16cyc", 0x7ffffb78, 0xffffffff, CELLPPU, { 0 }},
++/* Mambo simulator trap */
++{ "support", X(31,998), 0xffffffff, CELLPPU, { 0 }},
+ };
+
+ const int powerpc_num_opcodes =
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/spu-dis.c binutils/opcodes/spu-dis.c
+--- binutils-2.16.1/opcodes/spu-dis.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils/opcodes/spu-dis.c 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,258 @@
++/* spu-dis.c -- Disassemble Spu instructions */
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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 <stdio.h>
++#include "sysdep.h"
++#include "dis-asm.h"
++#include "opcode/spu.h"
++
++/* This file provides a disassembler function which uses
++ the disassembler interface defined in dis-asm.h. */
++
++static void init_spu_disassemble(void);
++
++extern const struct spu_opcode spu_opcodes[];
++extern const int spu_num_opcodes;
++
++static const struct spu_opcode *spu_disassemble_table[(1<<11)];
++
++static void
++init_spu_disassemble()
++{
++ int i;
++ /* If two instructions have the same opcode then we prefer the first
++ * one. In most cases it is just an alternate mnemonic. */
++ for (i = 0; i < spu_num_opcodes; i++)
++ {
++ int o = spu_opcodes[i].opcode;
++ if (o >= (1 << 11))
++ abort();
++ if (spu_disassemble_table[o] == 0)
++ spu_disassemble_table[o] = &spu_opcodes[i];
++ }
++}
++
++/* Determine the instruction from the 10 least significant bits. */
++static const struct spu_opcode *
++get_index_for_opcode(unsigned int insn)
++{
++ const struct spu_opcode *index;
++ unsigned int opcode = insn >> (32-11);
++
++ /* Init the table. This assumes that element 0/opcode 0 (currently
++ * NOP) is always used */
++ if (spu_disassemble_table[0] == 0)
++ init_spu_disassemble();
++
++ if ((index = spu_disassemble_table[opcode & 0x780]) != 0
++ && index->insn_type == RRR)
++ return index;
++
++ if ((index = spu_disassemble_table[opcode & 0x7f0]) != 0
++ && (index->insn_type == RI18 || index->insn_type == LBT))
++ return index;
++
++ if ((index = spu_disassemble_table[opcode & 0x7f8]) != 0
++ && index->insn_type == RI10)
++ return index;
++
++ if ((index = spu_disassemble_table[opcode & 0x7fc]) != 0
++ && (index->insn_type == RI16))
++ return index;
++
++ if ((index = spu_disassemble_table[opcode & 0x7fe]) != 0
++ && (index->insn_type == RI8))
++ return index;
++
++ if ((index = spu_disassemble_table[opcode & 0x7ff]) != 0)
++ {
++ return index;
++ }
++
++ return 0;
++}
++
++/* Print a Spu instruction. */
++
++int
++print_insn_spu (memaddr, info)
++ bfd_vma memaddr;
++ struct disassemble_info *info;
++{
++ bfd_byte buffer[4];
++ int value;
++ int hex_value;
++ int status;
++ unsigned int insn;
++ const struct spu_opcode *index;
++ enum spu_insns tag;
++
++ status = (*info->read_memory_func) (memaddr, buffer, 4, info);
++ if (status != 0)
++ {
++ (*info->memory_error_func) (status, memaddr, info);
++ return -1;
++ }
++
++ insn = bfd_getb32 (buffer);
++
++ index = get_index_for_opcode(insn);
++
++ if (index == 0)
++ {
++ (*info->fprintf_func) (info->stream, ".long 0x%x", insn);
++ }
++ else
++ {
++ int i;
++ int paren = 0;
++ tag = (enum spu_insns)(index - spu_opcodes);
++ (*info->fprintf_func) (info->stream, "%s", index->mnemonic);
++ if (tag == M_BI || tag == M_BISL || tag == M_IRET || tag == M_BISLED
++ || tag == M_BIHNZ || tag == M_BIHZ || tag == M_BINZ || tag == M_BIZ
++ || tag == M_SYNC || tag == M_HBR)
++ {
++ int fb = (insn >> (32-18)) & 0x7f;
++ if (fb & 0x40)
++ (*info->fprintf_func) (info->stream, tag == M_SYNC ? "c" : "p");
++ if (fb & 0x20)
++ (*info->fprintf_func) (info->stream, "d");
++ if (fb & 0x10)
++ (*info->fprintf_func) (info->stream, "e");
++ }
++ if (index->arg[0] != 0)
++ (*info->fprintf_func) (info->stream, "\t");
++ hex_value = 0;
++ for (i = 1; i <= index->arg[0]; i++)
++ {
++ int arg = index->arg[i];
++ if (arg != A_P && !paren && i > 1)
++ (*info->fprintf_func) (info->stream, ",");
++
++ switch (arg)
++ {
++ case A_T:
++ (*info->fprintf_func) (info->stream, "$%d", DECODE_INSN_RT(insn));
++ break;
++ case A_A:
++ (*info->fprintf_func) (info->stream, "$%d", DECODE_INSN_RA(insn));
++ break;
++ case A_B:
++ (*info->fprintf_func) (info->stream, "$%d", DECODE_INSN_RB(insn));
++ break;
++ case A_C:
++ (*info->fprintf_func) (info->stream, "$%d", DECODE_INSN_RC(insn));
++ break;
++ case A_S:
++ (*info->fprintf_func) (info->stream, "$sp%d", DECODE_INSN_RA(insn));
++ break;
++ case A_H:
++ (*info->fprintf_func) (info->stream, "$ch%d", DECODE_INSN_RA(insn));
++ break;
++ case A_P:
++ paren++;
++ (*info->fprintf_func) (info->stream, "(");
++ break;
++ case A_U7A:
++ (*info->fprintf_func) (info->stream, "%d", 173 - DECODE_INSN_U8(insn));
++ break;
++ case A_U7B:
++ (*info->fprintf_func) (info->stream, "%d", 155 - DECODE_INSN_U8(insn));
++ break;
++ case A_S3:
++ case A_S6:
++ case A_S7:
++ case A_S7N:
++ case A_U3:
++ case A_U5:
++ case A_U6:
++ case A_U7:
++ hex_value = DECODE_INSN_I7(insn);
++ (*info->fprintf_func) (info->stream, "%d", hex_value);
++ break;
++ case A_S11:
++ (*info->print_address_func) (memaddr + DECODE_INSN_I9a(insn) * 4, info);
++ break;
++ case A_S11I:
++ (*info->print_address_func) (memaddr + DECODE_INSN_I9b(insn) * 4, info);
++ break;
++ case A_S10:
++ case A_S10B:
++ hex_value = DECODE_INSN_I10(insn);
++ (*info->fprintf_func) (info->stream, "%d", hex_value);
++ break;
++ case A_S14:
++ hex_value = DECODE_INSN_I10(insn) * 16;
++ (*info->fprintf_func) (info->stream, "%d", hex_value);
++ break;
++ case A_S16:
++ hex_value = DECODE_INSN_I16(insn);
++ (*info->fprintf_func) (info->stream, "%d", hex_value);
++ break;
++ case A_X16:
++ hex_value = DECODE_INSN_U16(insn);
++ (*info->fprintf_func) (info->stream, "%u", hex_value);
++ break;
++ case A_R18:
++ value = DECODE_INSN_I16(insn) * 4;
++ if (value == 0)
++ (*info->fprintf_func) (info->stream, "%d", value);
++ else
++ {
++ hex_value = (int)(memaddr + value);
++ (*info->print_address_func) (hex_value & 0x3ffff, info);
++ }
++ break;
++ case A_S18:
++ value = DECODE_INSN_U16(insn) * 4;
++ if (value == 0)
++ (*info->fprintf_func) (info->stream, "%d", value);
++ else
++ (*info->print_address_func) (value, info);
++ break;
++ case A_U18:
++ value = DECODE_INSN_U18(insn);
++ if (value == 0 || !(*info->symbol_at_address_func)(0, info))
++ {
++ hex_value = value;
++ (*info->fprintf_func) (info->stream, "%u", value);
++ }
++ else
++ (*info->print_address_func) (value, info);
++ break;
++ case A_U14:
++ hex_value = DECODE_INSN_U14(insn);
++ (*info->fprintf_func) (info->stream, "%u", hex_value);
++ break;
++ }
++ if (arg != A_P && paren)
++ {
++ (*info->fprintf_func) (info->stream, ")");
++ paren--;
++ }
++ }
++ if (hex_value > 16)
++ (*info->fprintf_func) (info->stream, "\t# %x", hex_value);
++ }
++ return 4;
++}
+diff --exclude '*.po' --exclude Makefile.in -ruN binutils-2.16.1/opcodes/spu-opc.c binutils/opcodes/spu-opc.c
+--- binutils-2.16.1/opcodes/spu-opc.c 1970-01-01 01:00:00.000000000 +0100
++++ binutils/opcodes/spu-opc.c 2006-03-30 01:23:21.000000000 +0200
+@@ -0,0 +1,47 @@
++/* spu-opc.c -- Spu opcode list */
++
++/* (C) Copyright
++ Sony Computer Entertainment, Inc.,
++ Toshiba Corporation,
++ International Business Machines Corporation,
++ 2001,2002,2003,2004,2005.
++
++ 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 "opcode/spu.h"
++
++/* This file holds the Spu opcode table */
++
++
++/*
++ Example contents of spu-insn.h
++ id_tag mode mode type opcode mnemonic asmtype dependency FPU L/S? branch? instruction
++ QUAD WORD (0,RC,RB,RA,RT) latency
++ APUOP(M_LQD, 1, 0, RI9, 0x1f8, "lqd", ASM_RI9IDX, 00012, FXU, 1, 0) Load Quadword d-form
++ */
++
++const struct spu_opcode spu_opcodes[] = {
++#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
++ { MACFORMAT, OPCODE, MNEMONIC, ASMFORMAT },
++#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
++ { MACFORMAT, OPCODE, MNEMONIC, ASMFORMAT },
++#include "opcode/spu-insns.h"
++#undef APUOP
++#undef APUOPFB
++};
++
++const int spu_num_opcodes =
++ sizeof (spu_opcodes) / sizeof (spu_opcodes[0]);
diff --git a/sys-devel/binutils/files/digest-binutils-2.17 b/sys-devel/binutils/files/digest-binutils-2.17
new file mode 100644
index 0000000..ca2db64
--- /dev/null
+++ b/sys-devel/binutils/files/digest-binutils-2.17
@@ -0,0 +1,9 @@
+MD5 d4dad607ead1f2ee9834f267c145733f binutils-2.17-patches-1.0.tar.bz2 8785
+RMD160 326fcf5a278a7aa9027d16ec90b0fefa32c3e3b2 binutils-2.17-patches-1.0.tar.bz2 8785
+SHA256 8d371229695e2c0d4045cffb15de1c43a9912245516029c59b2a606184711f11 binutils-2.17-patches-1.0.tar.bz2 8785
+MD5 7454b5531542f8018f9d959eb3d8a233 binutils-2.17-uclibc-patches-1.0.tar.bz2 1569
+RMD160 b48156b39bb84b1955ac66e8d0473e50e7780ea9 binutils-2.17-uclibc-patches-1.0.tar.bz2 1569
+SHA256 9d63c8d2450f0ac8e164cf30c2e96b4fd9fe95356a9426526545445169c810c6 binutils-2.17-uclibc-patches-1.0.tar.bz2 1569
+MD5 e26e2e06b6e4bf3acf1dc8688a94c0d1 binutils-2.17.tar.bz2 13795751
+RMD160 3995d7ed97f115e76ce55b4c1f5256d53559c84f binutils-2.17.tar.bz2 13795751
+SHA256 e2c33ce6f23c9a366f109ced295626cb2f8bd6b2f08ff9df6dafb5448505a25e binutils-2.17.tar.bz2 13795751