diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2006-07-20 18:09:52 +0000 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2006-07-20 18:09:52 +0000 |
commit | 4d4d5b19a15f08061db280f9338eace51ebc304d (patch) | |
tree | 2b057e51c6c49260db471e2f664afcadb4dc9f81 /sys-devel/binutils/files/binutils-2.17-cell.patch | |
parent | the default scripts expect the images in the cell dir (diff) | |
download | lu_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/binutils/files/binutils-2.17-cell.patch')
-rw-r--r-- | sys-devel/binutils/files/binutils-2.17-cell.patch | 4735 |
1 files changed, 4735 insertions, 0 deletions
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]); |