]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
This commit was manufactured by cvs2svn to create branch
authornobody <>
Thu, 16 Sep 2004 14:52:13 +0000 (14:52 +0000)
committernobody <>
Thu, 16 Sep 2004 14:52:13 +0000 (14:52 +0000)
'drow_intercu-20040221-branch'.

Cherrypick from master 2004-09-16 14:52:12 UTC Alan Modra <amodra@gmail.com> ' * elf-bfd.h (struct elf_link_hash_entry): Replace elf_link_hash_flags':
    bfd/cpu-crx.c
    bfd/elf32-crx.c
    bfd/elf32-sh-symbian.c
    bfd/m88kopenbsd.c
    config/mh-ppc-darwin
    config/mt-gnu
    gdb/bsd-kvm.c
    gdb/bsd-kvm.h
    gdb/config/i386/i386.mt
    gdb/config/m68k/nbsd.mt
    gdb/config/m68k/nbsdelf.mh
    gdb/config/m68k/obsd.mh
    gdb/config/m68k/obsd.mt
    gdb/config/m88k/obsd.mh
    gdb/config/m88k/obsd.mt
    gdb/config/pa/linux.mh
    gdb/config/pa/linux.mt
    gdb/config/pa/nm-linux.h
    gdb/config/pa/obsd.mh
    gdb/config/pa/obsd.mt
    gdb/config/pa/tm-linux.h
    gdb/config/powerpc/obsd.mh
    gdb/config/powerpc/obsd.mt
    gdb/config/vax/nbsd.mt
    gdb/config/vax/nbsdaout.mh
    gdb/config/vax/nbsdelf.mh
    gdb/config/vax/nm-nbsdaout.h
    gdb/config/vax/obsd.mh
    gdb/config/vax/vax.mh
    gdb/gdb_ptrace.h
    gdb/hppa-linux-nat.c
    gdb/hppa-linux-tdep.c
    gdb/hppabsd-nat.c
    gdb/hppabsd-tdep.c
    gdb/i386nbsd-nat.c
    gdb/inf-child.c
    gdb/inf-child.h
    gdb/inf-ptrace.c
    gdb/inf-ptrace.h
    gdb/m68kbsd-nat.c
    gdb/m68kbsd-tdep.c
    gdb/m88k-tdep.c
    gdb/m88k-tdep.h
    gdb/m88kbsd-nat.c
    gdb/mi/gdb-mi.el
    gdb/observer.sh
    gdb/po/gdbtext
    gdb/ppcobsd-nat.c
    gdb/ppcobsd-tdep.c
    gdb/ppcobsd-tdep.h
    gdb/regset.c
    gdb/symfile-mem.c
    gdb/testsuite/gdb.ada/gnat_ada.gin
    gdb/testsuite/gdb.arch/e500-prologue.c
    gdb/testsuite/gdb.arch/e500-prologue.exp
    gdb/testsuite/gdb.arch/i386-cpuid.h
    gdb/testsuite/gdb.arch/i386-sse.c
    gdb/testsuite/gdb.arch/i386-sse.exp
    gdb/testsuite/gdb.arch/powerpc-aix-prologue.c
    gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp
    gdb/testsuite/gdb.asm/pa.inc
    gdb/testsuite/gdb.base/call-sc.c
    gdb/testsuite/gdb.base/call-sc.exp
    gdb/testsuite/gdb.base/lineinc.c
    gdb/testsuite/gdb.base/lineinc.exp
    gdb/testsuite/gdb.base/lineinc1.h
    gdb/testsuite/gdb.base/lineinc2.h
    gdb/testsuite/gdb.base/lineinc3.h
    gdb/testsuite/gdb.base/sep-proc.c
    gdb/testsuite/gdb.base/sep.c
    gdb/testsuite/gdb.base/sep.exp
    gdb/testsuite/gdb.base/sigaltstack.c
    gdb/testsuite/gdb.base/sigaltstack.exp
    gdb/testsuite/gdb.base/sigbpt.c
    gdb/testsuite/gdb.base/sigbpt.exp
    gdb/testsuite/gdb.base/siginfo.c
    gdb/testsuite/gdb.base/siginfo.exp
    gdb/testsuite/gdb.base/signull.c
    gdb/testsuite/gdb.base/signull.exp
    gdb/testsuite/gdb.base/sigstep.c
    gdb/testsuite/gdb.base/sigstep.exp
    gdb/testsuite/gdb.base/unload.c
    gdb/testsuite/gdb.base/unload.exp
    gdb/testsuite/gdb.base/unloadshr.c
    gdb/testsuite/gdb.fortran/Makefile.in
    gdb/testsuite/gdb.gdb/selftest.exp
    gdb/testsuite/gdb.java/jmain.exp
    gdb/testsuite/gdb.java/jmain.java
    gdb/testsuite/gdb.stabs/exclfwd.exp
    gdb/testsuite/gdb.stabs/exclfwd.h
    gdb/testsuite/gdb.stabs/exclfwd1.c
    gdb/testsuite/gdb.stabs/exclfwd2.c
    gdb/testsuite/gdb.threads/bp_in_thread.exp
    gdb/testsuite/gdb.threads/manythreads.c
    gdb/testsuite/gdb.threads/manythreads.exp
    gdb/testsuite/gdb.threads/pthread_cond_wait.c
    gdb/testsuite/gdb.threads/pthread_cond_wait.exp
    gdb/testsuite/gdb.threads/staticthreads.c
    gdb/testsuite/gdb.threads/staticthreads.exp
    gdb/testsuite/gdb.threads/thread_check.c
    gdb/testsuite/gdb.threads/thread_check.exp
    gdb/testsuite/gdb.threads/watchthreads.exp
    gdb/testsuite/lib/cp-support.exp
    gdb/vax-nat.c
    gdb/vaxbsd-nat.c
    gdb/vaxnbsd-tdep.c
    include/elf/crx.h
    include/gdb/sim-ppc.h
    include/opcode/crx.h
    opcodes/crx-dis.c
    opcodes/crx-opc.c
    sim/mn10300/am33-2.igen
    sim/ppc/gdb-sim.c
    sim/testsuite/sim/mips/fpu64-ps-sb1.s
    sim/testsuite/sim/mips/fpu64-ps.s
    sim/testsuite/sim/mips/mdmx-ob-sb1.s
    sim/testsuite/sim/mips/mdmx-ob.s
    sim/testsuite/sim/mips/utils-fpu.inc
    sim/testsuite/sim/mips/utils-mdmx.inc
    sim/testsuite/sim/sh/bandor.s
    sim/testsuite/sim/sh/bandornot.s
    sim/testsuite/sim/sh/bclr.s
    sim/testsuite/sim/sh/bld.s
    sim/testsuite/sim/sh/bldnot.s
    sim/testsuite/sim/sh/bset.s
    sim/testsuite/sim/sh/bst.s
    sim/testsuite/sim/sh/bxor.s
    sim/testsuite/sim/sh/clip.s
    sim/testsuite/sim/sh/div.s
    sim/testsuite/sim/sh/fail.s
    sim/testsuite/sim/sh/fsca.s
    sim/testsuite/sim/sh/fsrra.s
    sim/testsuite/sim/sh/mov.s
    sim/testsuite/sim/sh/mulr.s
    sim/testsuite/sim/sh/pass.s
    sim/testsuite/sim/sh/pushpop.s
    sim/testsuite/sim/sh/resbank.s

137 files changed:
bfd/cpu-crx.c [new file with mode: 0644]
bfd/elf32-crx.c [new file with mode: 0644]
bfd/elf32-sh-symbian.c [new file with mode: 0644]
bfd/m88kopenbsd.c [new file with mode: 0644]
config/mh-ppc-darwin [new file with mode: 0644]
config/mt-gnu [new file with mode: 0644]
gdb/bsd-kvm.c [new file with mode: 0644]
gdb/bsd-kvm.h [new file with mode: 0644]
gdb/config/i386/i386.mt [new file with mode: 0644]
gdb/config/m68k/nbsd.mt [new file with mode: 0644]
gdb/config/m68k/nbsdelf.mh [new file with mode: 0644]
gdb/config/m68k/obsd.mh [new file with mode: 0644]
gdb/config/m68k/obsd.mt [new file with mode: 0644]
gdb/config/m88k/obsd.mh [new file with mode: 0644]
gdb/config/m88k/obsd.mt [new file with mode: 0644]
gdb/config/pa/linux.mh [new file with mode: 0644]
gdb/config/pa/linux.mt [new file with mode: 0644]
gdb/config/pa/nm-linux.h [new file with mode: 0644]
gdb/config/pa/obsd.mh [new file with mode: 0644]
gdb/config/pa/obsd.mt [new file with mode: 0644]
gdb/config/pa/tm-linux.h [new file with mode: 0644]
gdb/config/powerpc/obsd.mh [new file with mode: 0644]
gdb/config/powerpc/obsd.mt [new file with mode: 0644]
gdb/config/vax/nbsd.mt [new file with mode: 0644]
gdb/config/vax/nbsdaout.mh [new file with mode: 0644]
gdb/config/vax/nbsdelf.mh [new file with mode: 0644]
gdb/config/vax/nm-nbsdaout.h [new file with mode: 0644]
gdb/config/vax/obsd.mh [new file with mode: 0644]
gdb/config/vax/vax.mh [new file with mode: 0644]
gdb/gdb_ptrace.h [new file with mode: 0644]
gdb/hppa-linux-nat.c [new file with mode: 0644]
gdb/hppa-linux-tdep.c [new file with mode: 0644]
gdb/hppabsd-nat.c [new file with mode: 0644]
gdb/hppabsd-tdep.c [new file with mode: 0644]
gdb/i386nbsd-nat.c [new file with mode: 0644]
gdb/inf-child.c [new file with mode: 0644]
gdb/inf-child.h [new file with mode: 0644]
gdb/inf-ptrace.c [new file with mode: 0644]
gdb/inf-ptrace.h [new file with mode: 0644]
gdb/m68kbsd-nat.c [new file with mode: 0644]
gdb/m68kbsd-tdep.c [new file with mode: 0644]
gdb/m88k-tdep.c [new file with mode: 0644]
gdb/m88k-tdep.h [new file with mode: 0644]
gdb/m88kbsd-nat.c [new file with mode: 0644]
gdb/mi/gdb-mi.el [new file with mode: 0644]
gdb/observer.sh [new file with mode: 0755]
gdb/po/gdbtext [new file with mode: 0755]
gdb/ppcobsd-nat.c [new file with mode: 0644]
gdb/ppcobsd-tdep.c [new file with mode: 0644]
gdb/ppcobsd-tdep.h [new file with mode: 0644]
gdb/regset.c [new file with mode: 0644]
gdb/symfile-mem.c [new file with mode: 0644]
gdb/testsuite/gdb.ada/gnat_ada.gin [new file with mode: 0644]
gdb/testsuite/gdb.arch/e500-prologue.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/e500-prologue.exp [new file with mode: 0644]
gdb/testsuite/gdb.arch/i386-cpuid.h [new file with mode: 0644]
gdb/testsuite/gdb.arch/i386-sse.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/i386-sse.exp [new file with mode: 0644]
gdb/testsuite/gdb.arch/powerpc-aix-prologue.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp [new file with mode: 0644]
gdb/testsuite/gdb.asm/pa.inc [new file with mode: 0644]
gdb/testsuite/gdb.base/call-sc.c [new file with mode: 0644]
gdb/testsuite/gdb.base/call-sc.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/lineinc.c [new file with mode: 0644]
gdb/testsuite/gdb.base/lineinc.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/lineinc1.h [new file with mode: 0644]
gdb/testsuite/gdb.base/lineinc2.h [new file with mode: 0644]
gdb/testsuite/gdb.base/lineinc3.h [new file with mode: 0644]
gdb/testsuite/gdb.base/sep-proc.c [new file with mode: 0644]
gdb/testsuite/gdb.base/sep.c [new file with mode: 0644]
gdb/testsuite/gdb.base/sep.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/sigaltstack.c [new file with mode: 0644]
gdb/testsuite/gdb.base/sigaltstack.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/sigbpt.c [new file with mode: 0644]
gdb/testsuite/gdb.base/sigbpt.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/siginfo.c [new file with mode: 0644]
gdb/testsuite/gdb.base/siginfo.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/signull.c [new file with mode: 0644]
gdb/testsuite/gdb.base/signull.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/sigstep.c [new file with mode: 0644]
gdb/testsuite/gdb.base/sigstep.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/unload.c [new file with mode: 0644]
gdb/testsuite/gdb.base/unload.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/unloadshr.c [new file with mode: 0644]
gdb/testsuite/gdb.fortran/Makefile.in [new file with mode: 0644]
gdb/testsuite/gdb.gdb/selftest.exp [new file with mode: 0644]
gdb/testsuite/gdb.java/jmain.exp [new file with mode: 0644]
gdb/testsuite/gdb.java/jmain.java [new file with mode: 0644]
gdb/testsuite/gdb.stabs/exclfwd.exp [new file with mode: 0644]
gdb/testsuite/gdb.stabs/exclfwd.h [new file with mode: 0644]
gdb/testsuite/gdb.stabs/exclfwd1.c [new file with mode: 0644]
gdb/testsuite/gdb.stabs/exclfwd2.c [new file with mode: 0644]
gdb/testsuite/gdb.threads/bp_in_thread.exp [new file with mode: 0644]
gdb/testsuite/gdb.threads/manythreads.c [new file with mode: 0644]
gdb/testsuite/gdb.threads/manythreads.exp [new file with mode: 0644]
gdb/testsuite/gdb.threads/pthread_cond_wait.c [new file with mode: 0644]
gdb/testsuite/gdb.threads/pthread_cond_wait.exp [new file with mode: 0644]
gdb/testsuite/gdb.threads/staticthreads.c [new file with mode: 0644]
gdb/testsuite/gdb.threads/staticthreads.exp [new file with mode: 0644]
gdb/testsuite/gdb.threads/thread_check.c [new file with mode: 0644]
gdb/testsuite/gdb.threads/thread_check.exp [new file with mode: 0644]
gdb/testsuite/gdb.threads/watchthreads.exp [new file with mode: 0644]
gdb/testsuite/lib/cp-support.exp [new file with mode: 0644]
gdb/vax-nat.c [new file with mode: 0644]
gdb/vaxbsd-nat.c [new file with mode: 0644]
gdb/vaxnbsd-tdep.c [new file with mode: 0644]
include/elf/crx.h [new file with mode: 0644]
include/gdb/sim-ppc.h [new file with mode: 0644]
include/opcode/crx.h [new file with mode: 0644]
opcodes/crx-dis.c [new file with mode: 0644]
opcodes/crx-opc.c [new file with mode: 0644]
sim/mn10300/am33-2.igen [new file with mode: 0644]
sim/ppc/gdb-sim.c [new file with mode: 0644]
sim/testsuite/sim/mips/fpu64-ps-sb1.s [new file with mode: 0644]
sim/testsuite/sim/mips/fpu64-ps.s [new file with mode: 0644]
sim/testsuite/sim/mips/mdmx-ob-sb1.s [new file with mode: 0644]
sim/testsuite/sim/mips/mdmx-ob.s [new file with mode: 0644]
sim/testsuite/sim/mips/utils-fpu.inc [new file with mode: 0644]
sim/testsuite/sim/mips/utils-mdmx.inc [new file with mode: 0644]
sim/testsuite/sim/sh/bandor.s [new file with mode: 0644]
sim/testsuite/sim/sh/bandornot.s [new file with mode: 0644]
sim/testsuite/sim/sh/bclr.s [new file with mode: 0644]
sim/testsuite/sim/sh/bld.s [new file with mode: 0644]
sim/testsuite/sim/sh/bldnot.s [new file with mode: 0644]
sim/testsuite/sim/sh/bset.s [new file with mode: 0644]
sim/testsuite/sim/sh/bst.s [new file with mode: 0644]
sim/testsuite/sim/sh/bxor.s [new file with mode: 0644]
sim/testsuite/sim/sh/clip.s [new file with mode: 0644]
sim/testsuite/sim/sh/div.s [new file with mode: 0644]
sim/testsuite/sim/sh/fail.s [new file with mode: 0644]
sim/testsuite/sim/sh/fsca.s [new file with mode: 0644]
sim/testsuite/sim/sh/fsrra.s [new file with mode: 0644]
sim/testsuite/sim/sh/mov.s [new file with mode: 0644]
sim/testsuite/sim/sh/mulr.s [new file with mode: 0644]
sim/testsuite/sim/sh/pass.s [new file with mode: 0644]
sim/testsuite/sim/sh/pushpop.s [new file with mode: 0644]
sim/testsuite/sim/sh/resbank.s [new file with mode: 0644]

diff --git a/bfd/cpu-crx.c b/bfd/cpu-crx.c
new file mode 100644 (file)
index 0000000..9636630
--- /dev/null
@@ -0,0 +1,39 @@
+/* BFD support for the CRX processor.
+   Copyright 2004 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.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+
+const bfd_arch_info_type bfd_crx_arch =
+  {
+    16,                /* 16 bits in a word.  */
+    32,                /* 32 bits in an address.  */
+    8,         /*  8 bits in a byte.  */
+    bfd_arch_crx, /* enum bfd_architecture arch.  */
+    bfd_mach_crx,
+    "crx",     /* Arch name.  */
+    "crx",     /* Printable name.  */
+    1,         /* Unsigned int section alignment power.  */
+    TRUE,      /* The one and only.  */
+    bfd_default_compatible, 
+    bfd_default_scan ,
+    0,
+  };
diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c
new file mode 100644 (file)
index 0000000..79b9c64
--- /dev/null
@@ -0,0 +1,1327 @@
+/* BFD back-end for National Semiconductor's CRX ELF
+   Copyright 2004 Free Software Foundation, Inc.
+   Written by Tomer Levi, NSC, Israel.
+
+   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.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/crx.h"
+
+static reloc_howto_type *elf_crx_reloc_type_lookup
+  (bfd *, bfd_reloc_code_real_type);
+static void elf_crx_info_to_howto
+  (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean elf32_crx_relax_delete_bytes
+  (bfd *, asection *, bfd_vma, int);
+static bfd_reloc_status_type crx_elf_final_link_relocate
+  (reloc_howto_type *, bfd *, bfd *, asection *,
+   bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
+   struct bfd_link_info *, asection *, int);
+static bfd_boolean elf32_crx_relocate_section
+  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+static asection * elf32_crx_gc_mark_hook
+  (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+   struct elf_link_hash_entry *, Elf_Internal_Sym *);
+static bfd_boolean elf32_crx_gc_sweep_hook
+  (bfd *, struct bfd_link_info *, asection *,
+   const Elf_Internal_Rela *);
+static bfd_boolean elf32_crx_relax_section
+  (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+static bfd_byte * elf32_crx_get_relocated_section_contents
+  (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+   bfd_byte *, bfd_boolean, asymbol **);
+
+/* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type.  */
+
+struct crx_reloc_map
+{
+  bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum.  */
+  unsigned short crx_reloc_type;          /* CRX relocation type.  */
+};
+
+static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
+{
+  {BFD_RELOC_NONE,         R_CRX_NONE},
+  {BFD_RELOC_CRX_REL4,     R_CRX_REL4},
+  {BFD_RELOC_CRX_REL8,     R_CRX_REL8},
+  {BFD_RELOC_CRX_REL8_CMP,  R_CRX_REL8_CMP},
+  {BFD_RELOC_CRX_REL16,            R_CRX_REL16},
+  {BFD_RELOC_CRX_REL24,            R_CRX_REL24},
+  {BFD_RELOC_CRX_REL32,            R_CRX_REL32},
+  {BFD_RELOC_CRX_REGREL12,  R_CRX_REGREL12},
+  {BFD_RELOC_CRX_REGREL22,  R_CRX_REGREL22},
+  {BFD_RELOC_CRX_REGREL28,  R_CRX_REGREL28},
+  {BFD_RELOC_CRX_REGREL32,  R_CRX_REGREL32},
+  {BFD_RELOC_CRX_ABS16,            R_CRX_ABS16},
+  {BFD_RELOC_CRX_ABS32,            R_CRX_ABS32},
+  {BFD_RELOC_CRX_NUM8,     R_CRX_NUM8},
+  {BFD_RELOC_CRX_NUM16,            R_CRX_NUM16},
+  {BFD_RELOC_CRX_NUM32,            R_CRX_NUM32},
+  {BFD_RELOC_CRX_IMM16,            R_CRX_IMM16},
+  {BFD_RELOC_CRX_IMM32,            R_CRX_IMM32},
+  {BFD_RELOC_CRX_SWITCH8,   R_CRX_SWITCH8},
+  {BFD_RELOC_CRX_SWITCH16,  R_CRX_SWITCH16},
+  {BFD_RELOC_CRX_SWITCH32,  R_CRX_SWITCH32}
+};
+
+static reloc_howto_type crx_elf_howto_table[] =
+{
+  HOWTO (R_CRX_NONE,           /* type */
+        0,                     /* rightshift */
+        2,                     /* size */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_NONE",          /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REL4,           /* type */
+        1,                     /* rightshift */
+        0,                     /* size */
+        4,                     /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REL4",          /* name */
+        FALSE,                 /* partial_inplace */
+        0xf,                   /* src_mask */
+        0xf,                   /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REL8,           /* type */
+        1,                     /* rightshift */
+        0,                     /* size */
+        8,                     /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REL8",          /* name */
+        FALSE,                 /* partial_inplace */
+        0xff,                  /* src_mask */
+        0xff,                  /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REL8_CMP,       /* type */
+        1,                     /* rightshift */
+        0,                     /* size */
+        8,                     /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REL8_CMP",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xff,                  /* src_mask */
+        0xff,                  /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REL16,          /* type */
+        1,                     /* rightshift */
+        1,                     /* size */
+        16,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REL16",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REL24,          /* type */
+        1,                     /* rightshift */
+        2,                     /* size */
+        24,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REL24",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffff,              /* src_mask */
+        0xffffff,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REL32,          /* type */
+        1,                     /* rightshift */
+        2,                     /* size */
+        32,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REL32",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REGREL12,       /* type */
+        0,                     /* rightshift */
+        1,                     /* size */
+        12,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REGREL12",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xfff,                 /* src_mask */
+        0xfff,                 /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REGREL22,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size */
+        22,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REGREL22",      /* name */
+        FALSE,                 /* partial_inplace */
+        0x3fffff,              /* src_mask */
+        0x3fffff,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REGREL28,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size */
+        28,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REGREL28",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xfffffff,             /* src_mask */
+        0xfffffff,             /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_REGREL32,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_REGREL32",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_ABS16,          /* type */
+        0,                     /* rightshift */
+        1,                     /* size */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_ABS16",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_ABS32,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_ABS32",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_NUM8,           /* type */
+        0,                     /* rightshift */
+        0,                     /* size */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_NUM8",          /* name */
+        FALSE,                 /* partial_inplace */
+        0xff,                  /* src_mask */
+        0xff,                  /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_NUM16,          /* type */
+        0,                     /* rightshift */
+        1,                     /* size */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_NUM16",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_NUM32,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_NUM32",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_IMM16,          /* type */
+        0,                     /* rightshift */
+        1,                     /* size */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_IMM16",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO (R_CRX_IMM32,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_bitfield,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_IMM32",         /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+  /* An 8 bit switch table entry.  This is generated for an expression
+     such as ``.byte L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH8,                /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH8",       /* name */
+        FALSE,                 /* partial_inplace */
+        0xff,                  /* src_mask */
+        0xff,                  /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* A 16 bit switch table entry.  This is generated for an expression
+     such as ``.word L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH16,       /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH16",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* A 32 bit switch table entry.  This is generated for an expression
+     such as ``.long L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH32,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH32",      /* name */
+        FALSE,                 /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        TRUE)                  /* pcrel_offset */
+};
+
+/* Retrieve a howto ptr using a BFD reloc_code.  */
+
+static reloc_howto_type *
+elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                          bfd_reloc_code_real_type code)
+{
+  unsigned int i;
+
+  for (i = 0; i < R_CRX_MAX; i++)
+    if (code == crx_reloc_map[i].bfd_reloc_enum)
+      return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
+
+  printf ("This relocation Type is not supported -0x%x\n", code);
+  return 0;
+}
+
+/* Retrieve a howto ptr using an internal relocation entry.  */
+
+static void
+elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+                      Elf_Internal_Rela *dst)
+{
+  unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+  BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
+  cache_ptr->howto = &crx_elf_howto_table[r_type];
+}
+
+/* Perform a relocation as part of a final link.  */
+
+static bfd_reloc_status_type
+crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
+                            bfd *output_bfd ATTRIBUTE_UNUSED,
+                            asection *input_section, bfd_byte *contents,
+                            bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
+                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                            asection *sec ATTRIBUTE_UNUSED,
+                            int is_local ATTRIBUTE_UNUSED)
+{
+  unsigned short r_type = howto->type;
+  bfd_byte *hit_data = contents + offset;
+  bfd_vma reloc_bits, check;
+
+  switch (r_type)
+    {
+     case R_CRX_IMM16:
+     case R_CRX_IMM32:
+     case R_CRX_ABS16:
+     case R_CRX_ABS32:
+     case R_CRX_REL8_CMP:
+     case R_CRX_REL16:
+     case R_CRX_REL24:
+     case R_CRX_REL32:
+     case R_CRX_REGREL12:
+     case R_CRX_REGREL22:
+     case R_CRX_REGREL28:
+     case R_CRX_REGREL32:
+       /* 'hit_data' is relative to the start of the instruction, not the
+         relocation offset. Advance it to account for the exact offset.  */
+       hit_data += 2;
+       break;
+
+     case R_CRX_REL4:
+       /* This relocation type is used only in 'Branch if Equal to 0'
+         instructions and requires special handling.  */
+       Rvalue -= 1;
+       break;
+
+     case R_CRX_NONE:
+       return bfd_reloc_ok;
+       break;
+
+     case R_CRX_SWITCH8:
+     case R_CRX_SWITCH16:
+     case R_CRX_SWITCH32:
+       /* We only care about the addend, where the difference between 
+         expressions is kept.  */
+       Rvalue = 0;
+       
+     default:
+       break;
+    }
+
+  if (howto->pc_relative)
+    {
+      /* Subtract the address of the section containing the location.  */
+      Rvalue -= (input_section->output_section->vma
+                + input_section->output_offset);
+      /* Subtract the position of the location within the section.  */
+      Rvalue -= offset;
+    }
+
+  /* Add in supplied addend.  */
+  Rvalue += addend;
+
+  /* Complain if the bitfield overflows, whether it is considered
+     as signed or unsigned.  */
+  check = Rvalue >> howto->rightshift;
+
+  /* Assumes two's complement.  This expression avoids
+     overflow if howto->bitsize is the number of bits in
+     bfd_vma.  */
+  reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+  if (((bfd_vma) check & ~reloc_bits) != 0
+      && (((bfd_vma) check & ~reloc_bits)
+         != (-(bfd_vma) 1 & ~reloc_bits)))
+    {
+      /* The above right shift is incorrect for a signed
+        value.  See if turning on the upper bits fixes the
+        overflow.  */
+      if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
+       {
+         check |= ((bfd_vma) - 1
+                   & ~((bfd_vma) - 1
+                       >> howto->rightshift));
+         if (((bfd_vma) check & ~reloc_bits)
+             != (-(bfd_vma) 1 & ~reloc_bits))
+           return bfd_reloc_overflow;
+       }
+      else
+       return bfd_reloc_overflow;
+    }
+
+  /* Drop unwanted bits from the value we are relocating to.  */
+  Rvalue >>= (bfd_vma) howto->rightshift;
+
+  /* Apply dst_mask to select only relocatable part of the insn.  */
+  Rvalue &= howto->dst_mask;
+
+  switch (howto->size)
+    {
+     case 0:
+       if (r_type == R_CRX_REL4)
+        {
+          Rvalue <<= 4;
+          Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
+        }
+
+       bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
+       break;
+
+     case 1:
+       if (r_type == R_CRX_REGREL12)
+        Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
+
+       bfd_put_16 (input_bfd, Rvalue, hit_data);
+       break;
+
+     case 2:
+       if (r_type == R_CRX_REL24
+          || r_type == R_CRX_REGREL22
+          || r_type == R_CRX_REGREL28)
+        Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
+                     bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
+
+       if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
+        /* Relocation on DATA is purely little-endian, that is, for a
+           multi-byte datum, the lowest address in memory contains the
+           little end of the datum, that is, the least significant byte.
+           Therefore we use BFD's byte Putting functions.  */
+        bfd_put_32 (input_bfd, Rvalue, hit_data);
+       else
+        /* Relocation on INSTRUCTIONS is different : Instructions are
+           word-addressable, that is, each word itself is arranged according
+           to little-endian convention, whereas the words are arranged with
+           respect to one another in BIG ENDIAN fashion.
+           When there is an immediate value that spans a word boundary, it is
+           split in a big-endian way with respect to the words.  */
+        {
+          bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
+          bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
+        }
+     break;
+
+     default:
+       return bfd_reloc_notsupported;
+    }
+
+  return bfd_reloc_ok;
+}
+
+/* Delete some bytes from a section while relaxing.  */
+
+static bfd_boolean
+elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
+                             bfd_vma addr, int count)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  unsigned int sec_shndx;
+  bfd_byte *contents;
+  Elf_Internal_Rela *irel, *irelend;
+  Elf_Internal_Rela *irelalign;
+  bfd_vma toaddr;
+  Elf_Internal_Sym *isym;
+  Elf_Internal_Sym *isymend;
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_link_hash_entry **end_hashes;
+  unsigned int symcount;
+
+  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+  contents = elf_section_data (sec)->this_hdr.contents;
+
+  /* The deletion must stop at the next ALIGN reloc for an aligment
+     power larger than the number of bytes we are deleting.  */
+
+  irelalign = NULL;
+  toaddr = sec->size;
+
+  irel = elf_section_data (sec)->relocs;
+  irelend = irel + sec->reloc_count;
+
+  /* Actually delete the bytes.  */
+  memmove (contents + addr, contents + addr + count,
+          (size_t) (toaddr - addr - count));
+  sec->size -= count;
+
+  /* Adjust all the relocs.  */
+  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+    {
+      /* Get the new reloc address.  */
+      if ((irel->r_offset > addr
+          && irel->r_offset < toaddr))
+       irel->r_offset -= count;
+    }
+
+  /* Adjust the local symbols defined in this section.  */
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+    {
+      if (isym->st_shndx == sec_shndx
+         && isym->st_value > addr
+         && isym->st_value < toaddr)
+       {
+         /* Adjust the addend of SWITCH relocations in this section, 
+            which reference this local symbol.  */
+         for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+           {
+             unsigned long r_symndx;
+             Elf_Internal_Sym *rsym;
+             bfd_vma addsym, subsym;
+
+             /* Skip if not a SWITCH relocation.  */
+             if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
+                 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
+                 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
+                 continue;
+
+             r_symndx = ELF32_R_SYM (irel->r_info);
+             rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
+
+             /* Skip if not the local adjusted symbol.  */
+             if (rsym != isym)
+               continue;
+
+             addsym = isym->st_value;
+             subsym = addsym - irel->r_addend;
+
+             /* Fix the addend only when -->> (addsym > addr >= subsym).  */
+             if (subsym <= addr)
+               irel->r_addend -= count;
+             else
+               continue;
+           }
+
+         isym->st_value -= count;
+       }
+    }
+
+  /* Now adjust the global symbols defined in this section.  */
+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+             - symtab_hdr->sh_info);
+  sym_hashes = elf_sym_hashes (abfd);
+  end_hashes = sym_hashes + symcount;
+
+  for (; sym_hashes < end_hashes; sym_hashes++)
+    {
+      struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+      if ((sym_hash->root.type == bfd_link_hash_defined
+          || sym_hash->root.type == bfd_link_hash_defweak)
+         && sym_hash->root.u.def.section == sec
+         && sym_hash->root.u.def.value > addr
+         && sym_hash->root.u.def.value < toaddr)
+       sym_hash->root.u.def.value -= count;
+    }
+
+  return TRUE;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+   which uses elf32_crx_relocate_section.  */
+
+static bfd_byte *
+elf32_crx_get_relocated_section_contents (bfd *output_bfd,
+                                         struct bfd_link_info *link_info,
+                                         struct bfd_link_order *link_order,
+                                         bfd_byte *data,
+                                         bfd_boolean relocatable,
+                                         asymbol **symbols)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  asection *input_section = link_order->u.indirect.section;
+  bfd *input_bfd = input_section->owner;
+  asection **sections = NULL;
+  Elf_Internal_Rela *internal_relocs = NULL;
+  Elf_Internal_Sym *isymbuf = NULL;
+
+  /* We only need to handle the case of relaxing, or of having a
+     particular set of section contents, specially.  */
+  if (relocatable
+      || elf_section_data (input_section)->this_hdr.contents == NULL)
+    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+                                                      link_order, data,
+                                                      relocatable,
+                                                      symbols);
+
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+         (size_t) input_section->size);
+
+  if ((input_section->flags & SEC_RELOC) != 0
+      && input_section->reloc_count > 0)
+    {
+      Elf_Internal_Sym *isym;
+      Elf_Internal_Sym *isymend;
+      asection **secpp;
+      bfd_size_type amt;
+
+      internal_relocs = (_bfd_elf_link_read_relocs
+                        (input_bfd, input_section, (PTR) NULL,
+                         (Elf_Internal_Rela *) NULL, FALSE));
+      if (internal_relocs == NULL)
+       goto error_return;
+
+      if (symtab_hdr->sh_info != 0)
+       {
+         isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+         if (isymbuf == NULL)
+           isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+                                           symtab_hdr->sh_info, 0,
+                                           NULL, NULL, NULL);
+         if (isymbuf == NULL)
+           goto error_return;
+       }
+
+      amt = symtab_hdr->sh_info;
+      amt *= sizeof (asection *);
+      sections = bfd_malloc (amt);
+      if (sections == NULL && amt != 0)
+       goto error_return;
+
+      isymend = isymbuf + symtab_hdr->sh_info;
+      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+       {
+         asection *isec;
+
+         if (isym->st_shndx == SHN_UNDEF)
+           isec = bfd_und_section_ptr;
+         else if (isym->st_shndx == SHN_ABS)
+           isec = bfd_abs_section_ptr;
+         else if (isym->st_shndx == SHN_COMMON)
+           isec = bfd_com_section_ptr;
+         else
+           isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+         *secpp = isec;
+       }
+
+      if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
+                                    input_section, data, internal_relocs,
+                                    isymbuf, sections))
+       goto error_return;
+
+      if (sections != NULL)
+       free (sections);
+      if (isymbuf != NULL
+         && symtab_hdr->contents != (unsigned char *) isymbuf)
+       free (isymbuf);
+      if (elf_section_data (input_section)->relocs != internal_relocs)
+       free (internal_relocs);
+    }
+
+  return data;
+
+ error_return:
+  if (sections != NULL)
+    free (sections);
+  if (isymbuf != NULL
+      && symtab_hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
+  if (internal_relocs != NULL
+      && elf_section_data (input_section)->relocs != internal_relocs)
+    free (internal_relocs);
+  return NULL;
+}
+
+/* Relocate a CRX ELF section.  */
+
+static bfd_boolean
+elf32_crx_relocate_section (bfd *output_bfd, 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;
+
+  if (info->relocatable)
+    return TRUE;
+
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  sym_hashes = 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;
+      bfd_vma relocation;
+      bfd_reloc_status_type r;
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      r_type = ELF32_R_TYPE (rel->r_info);
+      howto = crx_elf_howto_table + (r_type);
+
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+      if (r_symndx < symtab_hdr->sh_info)
+       {
+         sym = local_syms + r_symndx;
+         sec = local_sections[r_symndx];
+         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+       }
+      else
+       {
+         bfd_boolean unresolved_reloc, warned;
+
+         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                  r_symndx, symtab_hdr, sym_hashes,
+                                  h, sec, relocation,
+                                  unresolved_reloc, warned);
+       }
+
+      r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
+                                       input_section,
+                                       contents, rel->r_offset,
+                                       relocation, rel->r_addend,
+                                       info, sec, h == NULL);
+
+      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, 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 TRUE;
+}
+
+/* This function handles relaxing for the CRX.
+
+   There's quite a few relaxing opportunites available on the CRX:
+
+       * bal/bcond:32 -> bal/bcond:16                             2 bytes
+       * bcond:16 -> bcond:8                                      2 bytes
+       * cmpbcond:24 -> cmpbcond:8                                2 bytes
+       * arithmetic imm32 -> arithmetic imm16                     2 bytes
+
+   Symbol- and reloc-reading infrastructure copied from elf-m10200.c.  */
+
+static bfd_boolean
+elf32_crx_relax_section (bfd *abfd, asection *sec,
+                        struct bfd_link_info *link_info, bfd_boolean *again)
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Rela *internal_relocs;
+  Elf_Internal_Rela *irel, *irelend;
+  bfd_byte *contents = NULL;
+  Elf_Internal_Sym *isymbuf = NULL;
+
+  /* Assume nothing changes.  */
+  *again = FALSE;
+
+  /* We don't have to do anything for a relocatable link, if
+     this section does not have relocs, or if this is not a
+     code section.  */
+  if (link_info->relocatable
+      || (sec->flags & SEC_RELOC) == 0
+      || sec->reloc_count == 0
+      || (sec->flags & SEC_CODE) == 0)
+    return TRUE;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+  /* Get a copy of the native relocations.  */
+  internal_relocs = (_bfd_elf_link_read_relocs
+                    (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+                     link_info->keep_memory));
+  if (internal_relocs == NULL)
+    goto error_return;
+
+  /* Walk through them looking for relaxing opportunities.  */
+  irelend = internal_relocs + sec->reloc_count;
+  for (irel = internal_relocs; irel < irelend; irel++)
+    {
+      bfd_vma symval;
+
+      /* If this isn't something that can be relaxed, then ignore
+        this reloc.  */
+      if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL32
+         && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
+         && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
+         && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
+       continue;
+
+      /* Get the section contents if we haven't done so already.  */
+      if (contents == NULL)
+       {
+         /* Get cached copy if it exists.  */
+         if (elf_section_data (sec)->this_hdr.contents != NULL)
+           contents = elf_section_data (sec)->this_hdr.contents;
+         /* Go get them off disk.  */
+         else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+           goto error_return;
+       }
+
+      /* Read this BFD's local symbols if we haven't done so already.  */
+      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+       {
+         isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+         if (isymbuf == NULL)
+           isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+                                           symtab_hdr->sh_info, 0,
+                                           NULL, NULL, NULL);
+         if (isymbuf == NULL)
+           goto error_return;
+       }
+
+      /* Get the value of the symbol referred to by the reloc.  */
+      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+       {
+         /* A local symbol.  */
+         Elf_Internal_Sym *isym;
+         asection *sym_sec;
+
+         isym = isymbuf + ELF32_R_SYM (irel->r_info);
+         if (isym->st_shndx == SHN_UNDEF)
+           sym_sec = bfd_und_section_ptr;
+         else if (isym->st_shndx == SHN_ABS)
+           sym_sec = bfd_abs_section_ptr;
+         else if (isym->st_shndx == SHN_COMMON)
+           sym_sec = bfd_com_section_ptr;
+         else
+           sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+         symval = (isym->st_value
+                   + sym_sec->output_section->vma
+                   + sym_sec->output_offset);
+       }
+      else
+       {
+         unsigned long indx;
+         struct elf_link_hash_entry *h;
+
+         /* An external symbol.  */
+         indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+         h = elf_sym_hashes (abfd)[indx];
+         BFD_ASSERT (h != NULL);
+
+         if (h->root.type != bfd_link_hash_defined
+             && h->root.type != bfd_link_hash_defweak)
+           /* This appears to be a reference to an undefined
+              symbol.  Just ignore it--it will be caught by the
+              regular reloc processing.  */
+           continue;
+
+         symval = (h->root.u.def.value
+                   + h->root.u.def.section->output_section->vma
+                   + h->root.u.def.section->output_offset);
+       }
+
+      /* For simplicity of coding, we are going to modify the section
+        contents, the section relocs, and the BFD symbol table.  We
+        must tell the rest of the code not to free up this
+        information.  It would be possible to instead create a table
+        of changes which have to be made, as is done in coff-mips.c;
+        that would be more work, but would require less memory when
+        the linker is run.  */
+
+      /* Try to turn a 32bit pc-relative branch/call into
+        a 16bit pc-relative branch/call.  */
+      if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
+       {
+         bfd_vma value = symval;
+
+         /* Deal with pc-relative gunk.  */
+         value -= (sec->output_section->vma + sec->output_offset);
+         value -= irel->r_offset;
+         value += irel->r_addend;
+
+         /* See if the value will fit in 16 bits, note the high value is
+            0xfffe + 2 as the target will be two bytes closer if we are
+            able to relax.  */
+         if ((long) value < 0x10000 && (long) value > -0x10002)
+           {
+             unsigned short code;
+
+             /* Get the opcode.  */
+             code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+             /* Verify it's a 'bal'/'bcond' and fix the opcode.  */
+             if ((code & 0xfff0) == 0x3170)
+               bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
+             else if ((code & 0xf0ff) == 0x707f)
+               bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
+             else
+               continue;
+
+             /* Note that we've changed the relocs, section contents, etc.  */
+             elf_section_data (sec)->relocs = internal_relocs;
+             elf_section_data (sec)->this_hdr.contents = contents;
+             symtab_hdr->contents = (unsigned char *) isymbuf;
+
+             /* Fix the relocation's type.  */
+             irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                          R_CRX_REL16);
+
+             /* Delete two bytes of data.  */
+             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+                                                  irel->r_offset + 2, 2))
+               goto error_return;
+
+             /* That will change things, so, we should relax again.
+                Note that this is not required, and it may be slow.  */
+             *again = TRUE;
+           }
+       }
+
+      /* Try to turn a 16bit pc-relative branch into an
+        8bit pc-relative branch.  */
+      if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
+       {
+         bfd_vma value = symval;
+
+         /* Deal with pc-relative gunk.  */
+         value -= (sec->output_section->vma + sec->output_offset);
+         value -= irel->r_offset;
+         value += irel->r_addend;
+
+         /* See if the value will fit in 8 bits, note the high value is
+            0xfc + 2 as the target will be two bytes closer if we are
+            able to relax.  */
+         if ((long) value < 0xfe && (long) value > -0x100)
+           {
+             unsigned short code;
+
+             /* Get the opcode.  */
+             code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+             /* Verify it's a 'bcond' opcode.  */
+             if ((code & 0xf0ff) != 0x707e)
+               continue;
+
+             /* Note that we've changed the relocs, section contents, etc.  */
+             elf_section_data (sec)->relocs = internal_relocs;
+             elf_section_data (sec)->this_hdr.contents = contents;
+             symtab_hdr->contents = (unsigned char *) isymbuf;
+
+             /* Fix the relocation's type.  */
+             irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                          R_CRX_REL8);
+
+             /* Delete two bytes of data.  */
+             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+                                                  irel->r_offset + 2, 2))
+               goto error_return;
+
+             /* That will change things, so, we should relax again.
+                Note that this is not required, and it may be slow.  */
+             *again = TRUE;
+           }
+       }
+
+      /* Try to turn a 24bit pc-relative cmp&branch into
+        an 8bit pc-relative cmp&branch.  */
+      if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
+       {
+         bfd_vma value = symval;
+
+         /* Deal with pc-relative gunk.  */
+         value -= (sec->output_section->vma + sec->output_offset);
+         value -= irel->r_offset;
+         value += irel->r_addend;
+
+         /* See if the value will fit in 8 bits, note the high value is
+            0x7e + 2 as the target will be two bytes closer if we are
+            able to relax.  */
+         if ((long) value < 0x100 && (long) value > -0x100)
+           {
+             unsigned short code;
+
+             /* Get the opcode.  */
+             code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+             /* Verify it's a 'cmp&branch' opcode.  */
+             if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
+              && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
+              && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0)
+               continue;
+
+             /* Note that we've changed the relocs, section contents, etc.  */
+             elf_section_data (sec)->relocs = internal_relocs;
+             elf_section_data (sec)->this_hdr.contents = contents;
+             symtab_hdr->contents = (unsigned char *) isymbuf;
+
+             /* Fix the opcode.  */
+             bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
+
+             /* Fix the relocation's type.  */
+             irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                          R_CRX_REL8_CMP);
+
+             /* Delete two bytes of data.  */
+             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+                                                  irel->r_offset + 4, 2))
+               goto error_return;
+
+             /* That will change things, so, we should relax again.
+                Note that this is not required, and it may be slow.  */
+             *again = TRUE;
+           }
+       }
+
+      /* Try to turn a 32bit immediate address into
+        a 16bit immediate address.  */
+      if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
+       {
+         bfd_vma value = symval;
+
+         /* See if the value will fit in 16 bits.  */
+         if ((long) value < 0x7fff && (long) value > -0x8000)
+           {
+             unsigned short code;
+
+             /* Get the opcode.  */
+             code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+             /* Verify it's a 'arithmetic double'.  */
+             if ((code & 0xf0f0) != 0x20f0)
+               continue;
+
+             /* Note that we've changed the relocs, section contents, etc.  */
+             elf_section_data (sec)->relocs = internal_relocs;
+             elf_section_data (sec)->this_hdr.contents = contents;
+             symtab_hdr->contents = (unsigned char *) isymbuf;
+
+             /* Fix the opcode.  */
+             bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
+
+             /* Fix the relocation's type.  */
+             irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                          R_CRX_IMM16);
+
+             /* Delete two bytes of data.  */
+             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+                                                  irel->r_offset + 2, 2))
+               goto error_return;
+
+             /* That will change things, so, we should relax again.
+                Note that this is not required, and it may be slow.  */
+             *again = TRUE;
+           }
+       }
+    }
+
+  if (isymbuf != NULL
+      && symtab_hdr->contents != (unsigned char *) isymbuf)
+    {
+      if (! link_info->keep_memory)
+       free (isymbuf);
+      else
+       {
+         /* Cache the symbols for elf_link_input_bfd.  */
+         symtab_hdr->contents = (unsigned char *) isymbuf;
+       }
+    }
+
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
+    {
+      if (! link_info->keep_memory)
+       free (contents);
+      else
+       {
+         /* Cache the section contents for elf_link_input_bfd.  */
+         elf_section_data (sec)->this_hdr.contents = contents;
+       }
+    }
+
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
+
+  return TRUE;
+
+ error_return:
+  if (isymbuf != NULL
+      && symtab_hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
+    free (contents);
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
+
+  return FALSE;
+}
+
+static asection *
+elf32_crx_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)
+    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+
+  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:
+      return NULL;
+    }
+}
+
+/* Update the got entry reference counts for the section being removed.  */
+
+static bfd_boolean
+elf32_crx_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)
+{
+  /* We don't support garbage collection of GOT and PLT relocs yet.  */
+  return TRUE;
+}
+
+/* Definitions for setting CRX target vector.  */
+#define TARGET_LITTLE_SYM              bfd_elf32_crx_vec
+#define TARGET_LITTLE_NAME             "elf32-crx"
+#define ELF_ARCH                       bfd_arch_crx
+#define ELF_MACHINE_CODE               EM_CRX
+#define ELF_MAXPAGESIZE                        0x1
+#define elf_symbol_leading_char                '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup        elf_crx_reloc_type_lookup
+#define elf_info_to_howto              elf_crx_info_to_howto
+#define elf_info_to_howto_rel          0
+#define elf_backend_relocate_section   elf32_crx_relocate_section
+#define bfd_elf32_bfd_relax_section    elf32_crx_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+                               elf32_crx_get_relocated_section_contents
+#define elf_backend_gc_mark_hook        elf32_crx_gc_mark_hook
+#define elf_backend_gc_sweep_hook       elf32_crx_gc_sweep_hook
+#define elf_backend_can_gc_sections     1
+#define elf_backend_rela_normal                1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-sh-symbian.c b/bfd/elf32-sh-symbian.c
new file mode 100644 (file)
index 0000000..adce088
--- /dev/null
@@ -0,0 +1,627 @@
+/* Renesas / SuperH specific support for Symbian 32-bit ELF files
+   Copyright 2004
+   Free Software Foundation, Inc.
+   Contributed by Red Hat
+
+   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.  */
+
+/* Stop elf32-sh.c from defining any target vectors.  */
+#define SH_TARGET_ALREADY_DEFINED
+#define sh_find_elf_flags           sh_symbian_find_elf_flags
+#define sh_elf_get_flags_from_mach  sh_symbian_elf_get_flags_from_mach 
+#include "elf32-sh.c"
+
+
+//#define DEBUG 1
+#define DEBUG 0
+
+#define DIRECTIVE_HEADER       "#<SYMEDIT>#\n"
+#define DIRECTIVE_IMPORT       "IMPORT "
+#define DIRECTIVE_EXPORT       "EXPORT "
+#define DIRECTIVE_AS           "AS "
+
+/* Macro to advance 's' until either it reaches 'e' or the
+   character pointed to by 's' is equal to 'c'.  If 'e' is
+   reached and DEBUG is enabled then the error message 'm'
+   is displayed.  */
+#define SKIP_UNTIL(s,e,c,m)                                    \
+  do                                                           \
+    {                                                          \
+      while (s < e && *s != c)                                 \
+       ++ s;                                                   \
+      if (s >= e)                                              \
+       {                                                       \
+          if (DEBUG)                                           \
+           fprintf (stderr, "Corrupt directive: %s\n", m);     \
+         result = FALSE;                                       \
+       }                                                       \
+    }                                                          \
+  while (0);                                                   \
+  if (!result)                                                 \
+     break;
+
+/* Like SKIP_UNTIL except there are two terminator characters
+   c1 and c2.  */
+#define SKIP_UNTIL2(s,e,c1,c2,m)                               \
+  do                                                           \
+    {                                                          \
+      while (s < e && *s != c1 && *s != c2)                    \
+       ++ s;                                                   \
+      if (s >= e)                                              \
+       {                                                       \
+          if (DEBUG)                                           \
+           fprintf (stderr, "Corrupt directive: %s\n", m);     \
+         result = FALSE;                                       \
+       }                                                       \
+    }                                                          \
+  while (0);                                                   \
+  if (!result)                                                 \
+     break;
+
+/* Macro to advance 's' until either it reaches 'e' or the
+   character pointed to by 's' is not equal to 'c'.  If 'e'
+   is reached and DEBUG is enabled then the error message
+   'm' is displayed.  */
+#define SKIP_WHILE(s,e,c,m)                                    \
+  do                                                           \
+    {                                                          \
+      while (s < e && *s == c)                                 \
+       ++ s;                                                   \
+      if (s >= e)                                              \
+       {                                                       \
+          if (DEBUG)                                           \
+           fprintf (stderr, "Corrupt directive: %s\n", m);     \
+         result = FALSE;                                       \
+       }                                                       \
+    }                                                          \
+  while (0);                                                   \
+  if (!result)                                                 \
+     break;
+
+
+typedef struct symbol_rename
+{
+  struct symbol_rename *       next;
+  bfd_byte *                   current_name;
+  bfd_byte *                   new_name;
+  struct elf_link_hash_entry * current_hash;
+  unsigned long                new_symndx;
+}
+symbol_rename;
+
+static symbol_rename * rename_list = NULL;
+
+/* Accumulate a list of symbols to be renamed.  */
+
+static bfd_boolean
+sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd,
+                     bfd_byte * current_name, bfd_byte * new_name)
+{
+  struct elf_link_hash_entry * new_hash;
+  symbol_rename * node;
+
+  if (DEBUG)
+    fprintf (stderr, "IMPORT '%s' AS '%s'\n", current_name, new_name);
+
+  for (node = rename_list; node; node = node->next)
+    if (strcmp (node->current_name, current_name) == 0)
+      {
+       if (strcmp (node->new_name, new_name) == 0)
+         /* Already added to rename list.  */
+         return TRUE;
+
+       bfd_set_error (bfd_error_invalid_operation);
+       _bfd_error_handler (_("%B: IMPORT AS directive for %s conceals previous IMPORT AS"),
+                           abfd, current_name);
+       return FALSE;       
+      }
+
+  if ((node = bfd_malloc (sizeof * node)) == NULL)
+    {
+      if (DEBUG)
+       fprintf (stderr, "IMPORT AS: No mem for new rename node\n");
+      return FALSE;
+    }
+
+  if ((node->current_name = bfd_malloc (strlen (current_name) + 1)) == NULL)
+    {
+      if (DEBUG)
+       fprintf (stderr, "IMPORT AS: No mem for current name field in rename node\n");
+      free (node);
+      return FALSE;
+    }
+  else
+    strcpy (node->current_name, current_name);
+  
+  if ((node->new_name = bfd_malloc (strlen (new_name) + 1)) == NULL)
+    {
+      if (DEBUG)
+       fprintf (stderr, "IMPORT AS: No mem for new name field in rename node\n");
+      free (node->current_name);
+      free (node);
+      return FALSE;
+    }
+  else
+    strcpy (node->new_name, new_name);
+
+  node->next = rename_list;
+  node->current_hash = NULL;
+  node->new_symndx = 0;
+  rename_list = node;
+
+  new_hash = elf_link_hash_lookup (elf_hash_table (info), node->new_name, TRUE, FALSE, TRUE);
+  bfd_elf_link_record_dynamic_symbol (info, new_hash);
+  if (new_hash->root.type == bfd_link_hash_new)
+    new_hash->root.type = bfd_link_hash_undefined;
+
+  return TRUE;
+}
+
+
+static bfd_boolean
+sh_symbian_import (bfd * abfd ATTRIBUTE_UNUSED, bfd_byte * name)
+{
+  if (DEBUG)
+    fprintf (stderr, "IMPORT '%s'\n", name);
+
+  /* XXX: Generate an import somehow ?  */
+
+  return TRUE;
+}
+
+static bfd_boolean
+sh_symbian_export (bfd * abfd ATTRIBUTE_UNUSED, bfd_byte * name)
+{
+  if (DEBUG)
+    fprintf (stderr, "EXPORT '%s'\n", name);
+
+  /* XXX: Generate an export somehow ?  */
+
+  return TRUE;
+}
+
+/* Process any magic embedded commands in the .directive. section.
+   Returns TRUE upon sucecss, but if it fails it sets bfd_error and
+   returns FALSE.  */
+
+static bfd_boolean
+sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd,
+                                     asection * sec, bfd_byte * contents)
+{
+  bfd_byte *s;
+  bfd_byte *e;
+  bfd_boolean result = TRUE;
+  bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size;
+
+  for (s = contents, e = s + sz; s < e;)
+    {
+      bfd_byte * directive = s;
+
+      switch (*s)
+       {
+         /* I want to use "case DIRECTIVE_HEADER [0]:" here but gcc won't let me :-(  */
+       case '#':
+         if (strcmp (s, DIRECTIVE_HEADER))
+           result = FALSE;
+         else
+           /* Just ignore the header.
+              XXX: Strictly speaking we ought to check that the header
+              is present and that it is the first thing in the file.  */
+           s += strlen (DIRECTIVE_HEADER) + 1;
+         break;
+
+       case 'I':
+         if (strncmp (s, DIRECTIVE_IMPORT, strlen (DIRECTIVE_IMPORT)))
+           result = FALSE;
+         else
+           {
+             bfd_byte * new_name;
+             bfd_byte * new_name_end;
+             bfd_byte   name_end_char;
+
+             /* Skip the IMPORT directive.  */
+             s += strlen (DIRECTIVE_IMPORT);
+
+             new_name = s;
+             /* Find the end of the new name.  */
+             while (s < e && *s != ' ' && *s != '\n')
+               ++ s;
+             if (s >= e)
+               {
+                 /* We have reached the end of the .directive section
+                    without encountering a string terminator.  This is
+                    allowed for IMPORT directives.  */
+                 new_name_end   = e - 1;
+                 name_end_char  = * new_name_end;
+                 * new_name_end = 0;
+                 result = sh_symbian_import (abfd, new_name);
+                 * new_name_end = name_end_char;
+                 break;
+               }
+
+             /* Remember where the name ends.  */
+             new_name_end = s;
+             /* Skip any whitespace before the 'AS'.  */
+             SKIP_WHILE (s, e, ' ', "IMPORT: Name just followed by spaces");
+             /* Terminate the new name.  (Do this after skiping...)  */
+             name_end_char = * new_name_end;
+             * new_name_end = 0;
+
+             /* Check to see if 'AS '... is present.  If se we have an IMPORT AS
+                directive, otherwise we have an IMPORT directive.  */
+             if (strncmp (s, DIRECTIVE_AS, strlen (DIRECTIVE_AS)))
+               {
+                 /* Skip the new-line at the end of the name.  */
+                 if (DEBUG && name_end_char != '\n')
+                   fprintf (stderr, "IMPORT: No newline at end of directive\n");
+                 else
+                   s ++;
+
+                 result = sh_symbian_import (abfd, new_name);
+
+                 /* Skip past the NUL character.  */
+                 if (* s ++ != 0)
+                   {
+                     if (DEBUG)
+                       fprintf (stderr, "IMPORT: No NUL at end of directive\n");
+                   }
+               }
+             else
+               {
+                 bfd_byte * current_name;
+                 bfd_byte * current_name_end;
+                 bfd_byte   current_name_end_char;
+
+                 /* Skip the 'AS '.  */
+                 s += strlen (DIRECTIVE_AS);
+                 /* Skip any white space after the 'AS '.  */
+                 SKIP_WHILE (s, e, ' ', "IMPORT AS: Nothing after AS");
+                 current_name = s;
+                 /* Find the end of the current name.  */
+                 SKIP_UNTIL2 (s, e, ' ', '\n', "IMPORT AS: No newline at the end of the current name");
+                 /* Skip (backwards) over spaces at the end of the current name.  */
+                 current_name_end = s;
+                 current_name_end_char = * current_name_end;
+
+                 SKIP_WHILE (s, e, ' ', "IMPORT AS: Current name just followed by spaces");
+                 /* Skip past the newline character.  */
+                 if (* s ++ != '\n')
+                   if (DEBUG)
+                     fprintf (stderr, "IMPORT AS: No newline at end of directive\n");
+
+                 /* Terminate the current name after having performed the skips.  */
+                 * current_name_end = 0;
+
+                 result = sh_symbian_import_as (info, abfd, current_name, new_name);
+
+                 /* The next character should be a NUL.  */
+                 if (* s != 0)
+                   {
+                     if (DEBUG)
+                       fprintf (stderr, "IMPORT AS: Junk at end of directive\n");
+                     result = FALSE;
+                   }
+                 s ++;
+
+                 * current_name_end = current_name_end_char;
+               }
+
+             /* Restore the characters we overwrote, since
+                the .directive section will be emitted.  */
+             * new_name_end = name_end_char;
+           }
+         break;
+
+       case 'E':
+         if (strncmp (s, DIRECTIVE_EXPORT, strlen (DIRECTIVE_EXPORT)))
+           result = FALSE;
+         else
+           {
+             bfd_byte * name;
+             bfd_byte * name_end;
+             bfd_byte   name_end_char;
+
+             /* Skip the directive.  */
+             s += strlen (DIRECTIVE_EXPORT);
+             name = s;
+             /* Find the end of the name to be exported.  */
+             SKIP_UNTIL (s, e, '\n', "EXPORT: no newline at end of directive");
+             /* Skip (backwards) over spaces at end of exported name.  */
+             for (name_end = s; name_end[-1] == ' '; name_end --)
+               ;
+             /* name_end now points at the first character after the
+                end of the exported name, so we can termiante it  */
+             name_end_char = * name_end;
+             * name_end = 0;
+             /* Skip passed the newline character.  */
+             s ++;
+
+             result = sh_symbian_export (abfd, name);
+
+             /* The next character should be a NUL.  */
+             if (* s != 0)
+               {
+                 if (DEBUG)
+                   fprintf (stderr, "EXPORT: Junk at end of directive\n");
+                 result = FALSE;
+               }
+             s++;
+
+             /* Restore the character we deleted.  */
+             * name_end = name_end_char;
+           }
+         break;
+
+       default:
+         result = FALSE;
+         break;
+       }
+
+      if (! result)
+       {
+         if (DEBUG)
+           fprintf (stderr, "offset into .directive section: %d\n", directive - contents);
+         
+         bfd_set_error (bfd_error_invalid_operation);
+         _bfd_error_handler (_("%B: Unrecognised .directive command: %s"),
+                             abfd, directive);
+         break;
+       }
+    }
+
+  return result;
+}
+
+
+/* Scan a bfd for a .directive section, and if found process it.
+   Returns TRUE upon success, FALSE otherwise.  */
+bfd_boolean bfd_elf32_sh_symbian_process_directives (struct bfd_link_info *info, bfd * abfd);
+
+bfd_boolean
+bfd_elf32_sh_symbian_process_directives (struct bfd_link_info *info, bfd * abfd)
+{
+  bfd_boolean result = FALSE;
+  bfd_byte *  contents;
+  asection *  sec = bfd_get_section_by_name (abfd, ".directive");
+  bfd_size_type sz;
+
+  if (!sec)
+    return TRUE;
+
+  sz = sec->rawsize ? sec->rawsize : sec->size;
+  contents = bfd_malloc (sz);
+
+  if (!contents)
+    bfd_set_error (bfd_error_no_memory);
+  else 
+    {
+      if (bfd_get_section_contents (abfd, sec, contents, 0, sz))
+       result = sh_symbian_process_embedded_commands (info, abfd, sec, contents);
+      free (contents);
+    }
+
+  return result;
+}
+
+/* Intercept the normal sh_relocate_section() function
+   and magle the relocs to allow for symbol renaming.  */
+
+static bfd_boolean
+sh_symbian_relocate_section (bfd *                  output_bfd,
+                            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)
+{
+  /* When performing a final link we implement the IMPORT AS directives.  */
+  if (!info->relocatable)
+    {
+      Elf_Internal_Rela *            rel;
+      Elf_Internal_Rela *            relend;
+      Elf_Internal_Shdr *            symtab_hdr;
+      struct elf_link_hash_entry **  sym_hashes;
+      struct elf_link_hash_entry **  sym_hashes_end;
+      struct elf_link_hash_table *   hash_table;
+      symbol_rename *                ptr;
+      bfd_size_type                  num_global_syms;
+      unsigned long                 num_local_syms;
+      
+      BFD_ASSERT (! elf_bad_symtab (input_bfd));
+      symtab_hdr       = & elf_tdata (input_bfd)->symtab_hdr;
+      hash_table       = elf_hash_table (info);
+      num_local_syms   = symtab_hdr->sh_info;
+      num_global_syms  = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+      num_global_syms -= num_local_syms;
+      sym_hashes       = elf_sym_hashes (input_bfd);
+      sym_hashes_end   = sym_hashes + num_global_syms;
+
+      /* First scan the rename table, caching the hash entry and the new index.  */
+      for (ptr = rename_list; ptr; ptr = ptr->next)
+       {
+         struct elf_link_hash_entry *   new_hash;
+         struct elf_link_hash_entry **  h;
+
+         ptr->current_hash = elf_link_hash_lookup (hash_table, ptr->current_name, FALSE, FALSE, TRUE);
+
+         if (ptr->current_hash == NULL)
+           {
+             if (DEBUG)
+               fprintf (stderr, "IMPORT AS: current symbol '%s' does not exist\n", ptr->current_name);
+             continue;
+           }
+         
+         new_hash = elf_link_hash_lookup (hash_table, ptr->new_name, FALSE, FALSE, TRUE);
+
+         /* If we could not find the symbol then it is a new, undefined symbol.
+            Symbian want this behaviour - ie they want to be able to rename the
+            reference in a reloc from one undefined symbol to another, new and
+            undefined symbol.  So we create that symbol here.  */
+         if (new_hash == NULL)
+           {
+             asection *                     psec = bfd_und_section_ptr;
+             Elf_Internal_Sym               new_sym;
+             bfd_vma                        new_value = 0;
+             bfd_boolean                    skip;
+             bfd_boolean                    override;
+             bfd_boolean                    type_change_ok;
+             bfd_boolean                    size_change_ok;
+
+             new_sym.st_value = 0;
+             new_sym.st_size  = 0;
+             new_sym.st_name  = -1;
+             new_sym.st_info  = ELF_ST_INFO (STB_GLOBAL, STT_FUNC);
+             new_sym.st_other = ELF_ST_VISIBILITY (STV_DEFAULT);
+             new_sym.st_shndx = SHN_UNDEF;
+
+             if (! _bfd_elf_merge_symbol (input_bfd, info, ptr->new_name, & new_sym, & psec,
+                                          & new_value, & new_hash, & skip, & override, & type_change_ok,
+                                          & size_change_ok))
+               {
+                 _bfd_error_handler (_("%B: Failed to add renamed symbol %s"),
+                                     input_bfd, ptr->new_name);
+                 continue;
+               }
+             /* XXX - should we check psec, skip, override etc ?  */
+
+             new_hash->root.type = bfd_link_hash_undefined;
+
+             /* Allow the symbol to become local if necessary.  */
+             if (new_hash->dynindx == -1)
+               new_hash->def_regular = 1;
+
+             if (DEBUG)
+               fprintf (stderr, "Created new symbol %s\n", ptr->new_name);
+           }
+
+         /* Convert the new_hash value into a index into the table of symbol hashes.  */
+         for (h = sym_hashes; h < sym_hashes_end; h ++)
+           {
+             if (* h == new_hash)
+               {
+                 ptr->new_symndx = h - sym_hashes + num_local_syms;
+                 if (DEBUG)
+                   fprintf (stderr, "Converted new hash to index of %ld\n", ptr->new_symndx);
+                 break;
+               }
+           }
+         /* If the new symbol is not in the hash table then it must be
+            because it is one of the newly created undefined symbols
+            manufactured above.  So we extend the sym has table here to
+            include this extra symbol.  */
+         if (h == sym_hashes_end)
+           {
+             struct elf_link_hash_entry **  new_sym_hashes;
+
+             /* This is not very efficient, but it works.  */
+             ++ num_global_syms;
+             new_sym_hashes = bfd_alloc (input_bfd, num_global_syms * sizeof * sym_hashes);
+             if (new_sym_hashes == NULL)
+               {
+                 if (DEBUG)
+                   fprintf (stderr, "Out of memory extending hash table\n");
+                 continue;
+               }
+             memcpy (new_sym_hashes, sym_hashes, (num_global_syms - 1) * sizeof * sym_hashes);
+             new_sym_hashes[num_global_syms - 1] = new_hash;
+             elf_sym_hashes (input_bfd) = sym_hashes = new_sym_hashes;
+             sym_hashes_end = sym_hashes + num_global_syms;
+             symtab_hdr->sh_size  = (num_global_syms + num_local_syms) * sizeof (Elf32_External_Sym);
+
+             ptr->new_symndx = num_global_syms - 1 + num_local_syms;
+
+             if (DEBUG)
+               fprintf (stderr, "Extended symbol hash table to insert new symbol as index %ld\n",
+                        ptr->new_symndx);
+           }
+       }
+
+      /* Walk the reloc list looking for references to renamed symbols.
+        When we find one, we alter the index in the reloc to point to the new symbol.  */
+      for (rel = relocs, relend = relocs + input_section->reloc_count;
+          rel < relend;
+          rel ++)
+       {
+         int                          r_type;
+         unsigned long                r_symndx;
+         struct elf_link_hash_entry * h;
+      
+         r_symndx = ELF32_R_SYM (rel->r_info);
+         r_type = ELF32_R_TYPE (rel->r_info);
+
+         /* Ignore unused relocs.  */
+         if ((r_type >= (int) R_SH_GNU_VTINHERIT
+              && r_type <= (int) R_SH_LABEL)
+             || r_type == (int) R_SH_NONE
+             || r_type < 0
+             || r_type >= R_SH_max)
+           continue;
+
+         /* Ignore relocs against local symbols.  */
+         if (r_symndx < num_local_syms)
+           continue;
+
+         BFD_ASSERT (r_symndx < (num_global_syms + num_local_syms));
+         h = sym_hashes[r_symndx - num_local_syms];
+         BFD_ASSERT (h != NULL);
+
+         while (   h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+         /* If the symbol is defined there is no need to rename it.
+            XXX - is this true ?  */
+         if (   h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak
+             || h->root.type == bfd_link_hash_undefweak)
+           continue;
+
+         for (ptr = rename_list; ptr; ptr = ptr->next)
+           if (h == ptr->current_hash)
+             {
+               BFD_ASSERT (ptr->new_symndx);
+               if (DEBUG)
+                 fprintf (stderr, "convert reloc %lx from using index %ld to using index %ld\n",
+                          (long) rel->r_info, (long) ELF32_R_SYM (rel->r_info), ptr->new_symndx);
+               rel->r_info = ELF32_R_INFO (ptr->new_symndx, r_type);
+               break;
+             }
+       }
+    }
+  
+  return sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+                                 contents, relocs, local_syms, local_sections);
+}
+
+static bfd_boolean
+sh_symbian_check_directives (bfd *abfd, struct bfd_link_info *info)
+{
+  return bfd_elf32_sh_symbian_process_directives (info, abfd);
+}
+
+#define TARGET_LITTLE_SYM      bfd_elf32_shl_symbian_vec
+#define TARGET_LITTLE_NAME      "elf32-shl-symbian"
+
+#undef  elf_backend_relocate_section
+#define elf_backend_relocate_section   sh_symbian_relocate_section
+#undef  elf_backend_check_directives
+#define elf_backend_check_directives    sh_symbian_check_directives
+
+#include "elf32-target.h"
diff --git a/bfd/m88kopenbsd.c b/bfd/m88kopenbsd.c
new file mode 100644 (file)
index 0000000..459d3b2
--- /dev/null
@@ -0,0 +1,33 @@
+/* BFD back-end for OpenBSD/m88k a.out binaries.
+   Copyright 2004 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.  */
+
+#define        TARGET_IS_BIG_ENDIAN_P
+
+#define        TARGET_PAGE_SIZE        4096
+
+#define        DEFAULT_ARCH            bfd_arch_m88k
+#define        DEFAULT_MID             M_88K_OPENBSD
+
+/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
+   remove whitespace added here, and thus will fail to concatenate
+   the tokens.  */
+#define MY(OP) CONCAT2 (m88kopenbsd_,OP)
+#define TARGETNAME "a.out-m88k-openbsd"
+
+#include "netbsd.h"
diff --git a/config/mh-ppc-darwin b/config/mh-ppc-darwin
new file mode 100644 (file)
index 0000000..44fd620
--- /dev/null
@@ -0,0 +1,6 @@
+# The -mdynamic-no-pic ensures that the compiler executable is built without
+# position-independent-code -- the usual default on Darwin. This fix speeds
+# compiles by 3-5%.
+
+BOOT_CFLAGS=-g -O2 -mdynamic-no-pic
+
diff --git a/config/mt-gnu b/config/mt-gnu
new file mode 100644 (file)
index 0000000..15bf417
--- /dev/null
@@ -0,0 +1 @@
+CXXFLAGS_FOR_TARGET = $(CXXFLAGS) -D_GNU_SOURCE
diff --git a/gdb/bsd-kvm.c b/gdb/bsd-kvm.c
new file mode 100644 (file)
index 0000000..64869e5
--- /dev/null
@@ -0,0 +1,307 @@
+/* BSD Kernel Data Access Library (libkvm) interface.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "cli/cli-cmds.h"
+#include "command.h"
+#include "frame.h"
+#include "regcache.h"
+#include "target.h"
+#include "value.h"
+#include "gdbcore.h"           /* for get_exec_file */
+
+#include "gdb_assert.h"
+#include <fcntl.h>
+#include <kvm.h>
+#ifdef HAVE_NLIST_H
+#include <nlist.h>
+#endif
+#include "readline/readline.h"
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include "bsd-kvm.h"
+
+/* Kernel memory interface descriptor.  */
+kvm_t *core_kd;
+
+/* Address of process control block.  */
+struct pcb *bsd_kvm_paddr;
+
+/* Pointer to architecture-specific function that reconstructs the
+   register state from PCB and supplies it to REGCACHE.  */
+int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
+
+/* Target ops for libkvm interface.  */
+struct target_ops bsd_kvm_ops;
+
+static void
+bsd_kvm_open (char *filename, int from_tty)
+{
+  char errbuf[_POSIX2_LINE_MAX];
+  char *execfile = NULL;
+  kvm_t *temp_kd;
+
+  target_preopen (from_tty);
+
+  if (filename)
+    {
+      char *temp;
+
+      filename = tilde_expand (filename);
+      if (filename[0] != '/')
+       {
+         temp = concat (current_directory, "/", filename, NULL);
+         xfree (filename);
+         filename = temp;
+       }
+    }
+
+  execfile = get_exec_file (0);
+  temp_kd = kvm_openfiles (execfile, filename, NULL, O_RDONLY, errbuf);
+  if (temp_kd == NULL)
+    error ("%s", errbuf);
+
+  unpush_target (&bsd_kvm_ops);
+  core_kd = temp_kd;
+  push_target (&bsd_kvm_ops);
+
+  target_fetch_registers (-1);
+
+  flush_cached_frames ();
+  select_frame (get_current_frame ());
+  print_stack_frame (get_selected_frame (), -1, 1);
+}
+
+static void
+bsd_kvm_close (int quitting)
+{
+  if (core_kd)
+    {
+      if (kvm_close (core_kd) == -1)
+       warning ("%s", kvm_geterr(core_kd));
+      core_kd = NULL;
+    }
+}
+
+static int
+bsd_kvm_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+                   int write, struct mem_attrib *attrib,
+                   struct target_ops *ops)
+{
+  if (write)
+    return kvm_write (core_kd, memaddr, myaddr, len);
+  else
+    return kvm_read (core_kd, memaddr, myaddr, len);
+
+  return -1;
+}
+
+/* Fetch process control block at address PADDR.  */
+
+static int
+bsd_kvm_fetch_pcb (struct pcb *paddr)
+{
+  struct pcb pcb;
+
+  if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
+    error ("%s", kvm_geterr (core_kd));
+
+  gdb_assert (bsd_kvm_supply_pcb);
+  return bsd_kvm_supply_pcb (current_regcache, &pcb);
+}
+
+static void
+bsd_kvm_fetch_registers (int regnum)
+{
+  struct nlist nl[2];
+
+  if (bsd_kvm_paddr)
+    {
+      bsd_kvm_fetch_pcb (bsd_kvm_paddr);
+      return;
+    }
+
+  /* On dumping core, BSD kernels store the faulting context (PCB)
+     in the variable "dumppcb".  */
+  memset (nl, 0, sizeof nl);
+  nl[0].n_name = "_dumppcb";
+
+  if (kvm_nlist (core_kd, nl) == -1)
+    error ("%s", kvm_geterr (core_kd));
+
+  if (nl[0].n_value != 0)
+    {
+      /* Found dumppcb. If it contains a valid context, return
+        immediately.  */
+      if (bsd_kvm_fetch_pcb ((struct pcb *) nl[0].n_value))
+       return;
+    }
+
+  /* Traditional BSD kernels have a process proc0 that should always
+     be present.  The address of proc0's PCB is stored in the variable
+     "proc0paddr".  */
+
+  memset (nl, 0, sizeof nl);
+  nl[0].n_name = "_proc0paddr";
+
+  if (kvm_nlist (core_kd, nl) == -1)
+    error ("%s", kvm_geterr (core_kd));
+
+  if (nl[0].n_value != 0)
+    {
+      struct pcb *paddr;
+
+      /* Found proc0paddr.  */
+      if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
+       error ("%s", kvm_geterr (core_kd));
+
+      bsd_kvm_fetch_pcb (paddr);
+      return;
+    }
+
+#ifdef HAVE_STRUCT_THREAD_TD_PCB
+  /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
+     lives in `struct proc' but in `struct thread'.  The `struct
+     thread' for the initial thread for proc0 can be found in the
+     variable "thread0".  */
+
+  memset (nl, 0, sizeof nl);
+  nl[0].n_name = "_thread0";
+
+  if (kvm_nlist (core_kd, nl) == -1)
+    error ("%s", kvm_geterr (core_kd));
+
+  if (nl[0].n_value != 0)
+    {
+      struct pcb *paddr;
+
+      /* Found thread0.  */
+      nl[0].n_value += offsetof (struct thread, td_pcb);
+      if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
+       error ("%s", kvm_geterr (core_kd));
+
+      bsd_kvm_fetch_pcb (paddr);
+      return;
+    }
+#endif
+
+  error ("Cannot find a valid PCB");
+}
+\f
+
+/* Kernel memory interface commands.  */
+struct cmd_list_element *bsd_kvm_cmdlist;
+
+static void
+bsd_kvm_cmd (char *arg, int fromtty)
+{
+  /* ??? Should this become an alias for "target kvm"?  */
+}
+
+#ifndef HAVE_STRUCT_THREAD_TD_PCB
+
+static void
+bsd_kvm_proc_cmd (char *arg, int fromtty)
+{
+  CORE_ADDR addr;
+
+  if (arg == NULL)
+    error_no_arg ("proc address");
+
+  if (core_kd == NULL)
+    error ("No kernel memory image.");
+
+  addr = parse_and_eval_address (arg);
+#ifdef HAVE_STRUCT_LWP
+  addr += offsetof (struct lwp, l_addr);
+#else
+  addr += offsetof (struct proc, p_addr);
+#endif
+
+  if (kvm_read (core_kd, addr, &bsd_kvm_paddr, sizeof bsd_kvm_paddr) == -1)
+    error ("%s", kvm_geterr (core_kd));
+
+  target_fetch_registers (-1);
+
+  flush_cached_frames ();
+  select_frame (get_current_frame ());
+  print_stack_frame (get_selected_frame (), -1, 1);
+}
+
+#endif
+
+static void
+bsd_kvm_pcb_cmd (char *arg, int fromtty)
+{
+  if (arg == NULL)
+    error_no_arg ("pcb address");
+
+  if (core_kd == NULL)
+    error ("No kernel memory image.");
+
+  bsd_kvm_paddr = (struct pcb *) parse_and_eval_address (arg);
+
+  target_fetch_registers (-1);
+
+  flush_cached_frames ();
+  select_frame (get_current_frame ());
+  print_stack_frame (get_selected_frame (), -1, 1);
+}
+
+/* Add the libkvm interface to the list of all possible targets and
+   register CUPPLY_PCB as the architecture-specific process control
+   block interpreter.  */
+
+void
+bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
+{
+  gdb_assert (bsd_kvm_supply_pcb == NULL);
+  bsd_kvm_supply_pcb = supply_pcb;
+
+  bsd_kvm_ops.to_shortname = "kvm";
+  bsd_kvm_ops.to_longname = "Kernel memory interface";
+  bsd_kvm_ops.to_doc = "Use a kernel virtual memory image as a target.\n\
+Optionally specify the filename of a core dump.";
+  bsd_kvm_ops.to_open = bsd_kvm_open;
+  bsd_kvm_ops.to_close = bsd_kvm_close;
+  bsd_kvm_ops.to_fetch_registers = bsd_kvm_fetch_registers;
+  bsd_kvm_ops.to_xfer_memory = bsd_kvm_xfer_memory;
+  bsd_kvm_ops.to_stratum = process_stratum;
+  bsd_kvm_ops.to_has_memory = 1;
+  bsd_kvm_ops.to_has_stack = 1;
+  bsd_kvm_ops.to_has_registers = 1;
+  bsd_kvm_ops.to_magic = OPS_MAGIC;
+
+  add_target (&bsd_kvm_ops);
+  
+  add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, "\
+Generic command for manipulating the kernel memory interface.",
+                 &bsd_kvm_cmdlist, "kvm ", 0, &cmdlist);
+
+#ifndef HAVE_STRUCT_THREAD_TD_PCB
+  add_cmd ("proc", class_obscure, bsd_kvm_proc_cmd,
+          "Set current context from proc address", &bsd_kvm_cmdlist);
+#endif
+  add_cmd ("pcb", class_obscure, bsd_kvm_pcb_cmd,
+          "Set current context from pcb address", &bsd_kvm_cmdlist);
+}
diff --git a/gdb/bsd-kvm.h b/gdb/bsd-kvm.h
new file mode 100644 (file)
index 0000000..0660776
--- /dev/null
@@ -0,0 +1,35 @@
+/* BSD Kernel Data Access Library (libkvm) interface.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 BSD_KVM_H
+#define BSD_KVM_H
+
+struct pcb;
+struct regcache;
+
+/* Add the libkvm interface to the list of all possible targets and
+   register CUPPLY_PCB as the architecture-specific process control
+   block interpreter.  */
+
+extern void
+  bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *));
+
+#endif /* bsd-kvm.h */
diff --git a/gdb/config/i386/i386.mt b/gdb/config/i386/i386.mt
new file mode 100644 (file)
index 0000000..d2eab6d
--- /dev/null
@@ -0,0 +1,2 @@
+# Target: i386
+TDEPFILES= i386-tdep.o i387-tdep.o
diff --git a/gdb/config/m68k/nbsd.mt b/gdb/config/m68k/nbsd.mt
new file mode 100644 (file)
index 0000000..db3e357
--- /dev/null
@@ -0,0 +1,3 @@
+# Target: NetBSD/m68k
+TDEPFILES= m68k-tdep.o m68kbsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
diff --git a/gdb/config/m68k/nbsdelf.mh b/gdb/config/m68k/nbsdelf.mh
new file mode 100644 (file)
index 0000000..c58e348
--- /dev/null
@@ -0,0 +1,5 @@
+# Host: NetBSD/m68k ELF
+NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-nbsd.h
+
+LOADLIBES= -lkvm
diff --git a/gdb/config/m68k/obsd.mh b/gdb/config/m68k/obsd.mh
new file mode 100644 (file)
index 0000000..54e4e9d
--- /dev/null
@@ -0,0 +1,6 @@
+# Host: OpenBSD/m68k
+NATDEPFILES= m68kbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o \
+       solib.o solib-sunos.o
+NAT_FILE= nm-nbsdaout.h
+
+LOADLIBES= -lkvm
diff --git a/gdb/config/m68k/obsd.mt b/gdb/config/m68k/obsd.mt
new file mode 100644 (file)
index 0000000..9853121
--- /dev/null
@@ -0,0 +1,3 @@
+# Target: OpenBSD/m68k
+TDEPFILES= m68k-tdep.o m68kbsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
diff --git a/gdb/config/m88k/obsd.mh b/gdb/config/m88k/obsd.mh
new file mode 100644 (file)
index 0000000..e9281bc
--- /dev/null
@@ -0,0 +1,3 @@
+# Host: OpenBSD/m88k
+NATDEPFILES= m88kbsd-nat.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-bsd.h
diff --git a/gdb/config/m88k/obsd.mt b/gdb/config/m88k/obsd.mt
new file mode 100644 (file)
index 0000000..36e61bb
--- /dev/null
@@ -0,0 +1,2 @@
+# Target: OpenBSD/m88k
+TDEPFILES= m88k-tdep.o corelow.o
diff --git a/gdb/config/pa/linux.mh b/gdb/config/pa/linux.mh
new file mode 100644 (file)
index 0000000..596857c
--- /dev/null
@@ -0,0 +1,8 @@
+# Host: Hewlett-Packard PA-RISC machine, running Linux
+XDEPFILES=
+NAT_FILE= nm-linux.h
+NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o gcore.o \
+       core-regset.o hppa-linux-nat.o linux-proc.o \
+       proc-service.o thread-db.o lin-lwp.o linux-nat.o
+
+LOADLIBES = -ldl -rdynamic
diff --git a/gdb/config/pa/linux.mt b/gdb/config/pa/linux.mt
new file mode 100644 (file)
index 0000000..d216866
--- /dev/null
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running Linux
+TDEPFILES= hppa-tdep.o hppa-linux-tdep.o glibc-tdep.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE=tm-linux.h
diff --git a/gdb/config/pa/nm-linux.h b/gdb/config/pa/nm-linux.h
new file mode 100644 (file)
index 0000000..08b7915
--- /dev/null
@@ -0,0 +1,32 @@
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 PA_NM_LINUX_H
+#define PA_NM_LINUX_H
+
+#include "config/nm-linux.h"
+
+#define U_REGS_OFFSET 0
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'.  */
+#define FETCH_INFERIOR_REGISTERS
+
+#endif
+
diff --git a/gdb/config/pa/obsd.mh b/gdb/config/pa/obsd.mh
new file mode 100644 (file)
index 0000000..2c3dba9
--- /dev/null
@@ -0,0 +1,3 @@
+# Host: OpenBSD/hppa
+NATDEPFILES= fork-child.o infptrace.o inftarg.o hppabsd-nat.o
+NAT_FILE= config/nm-bsd.h
diff --git a/gdb/config/pa/obsd.mt b/gdb/config/pa/obsd.mt
new file mode 100644 (file)
index 0000000..b7a6888
--- /dev/null
@@ -0,0 +1,3 @@
+# Target: OpenBSD/hppa
+TDEPFILES= hppa-tdep.o hppabsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
diff --git a/gdb/config/pa/tm-linux.h b/gdb/config/pa/tm-linux.h
new file mode 100644 (file)
index 0000000..e8b31c5
--- /dev/null
@@ -0,0 +1,30 @@
+/* Definitions to target GDB to GNU/Linux on hppa-linux.
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 TM_LINUX_H
+#define TM_LINUX_H
+
+#include "pa/tm-hppa.h"
+#include "config/tm-linux.h"
+
+#undef IN_SOLIB_CALL_TRAMPOLINE
+#undef SKIP_TRAMPOLINE_CODE
+
+#endif /* #ifndef TM_LINUX_H */
diff --git a/gdb/config/powerpc/obsd.mh b/gdb/config/powerpc/obsd.mh
new file mode 100644 (file)
index 0000000..0482d3d
--- /dev/null
@@ -0,0 +1,3 @@
+# Host: OpenBSD/powerpc
+NATDEPFILES= ppcobsd-nat.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-bsd.h
diff --git a/gdb/config/powerpc/obsd.mt b/gdb/config/powerpc/obsd.mt
new file mode 100644 (file)
index 0000000..a0adcdb
--- /dev/null
@@ -0,0 +1,4 @@
+# Target: OpenBSD/powerpc
+TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcobsd-tdep.o \
+       corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= tm-nbsd.h
diff --git a/gdb/config/vax/nbsd.mt b/gdb/config/vax/nbsd.mt
new file mode 100644 (file)
index 0000000..dfe746f
--- /dev/null
@@ -0,0 +1,3 @@
+# Target: NetBSD/vax
+TDEPFILES= vax-tdep.o vaxnbsd-tdep.o corelow.o solib.o solib-svr4.o
+DEPRECATED_TM_FILE= solib.h
diff --git a/gdb/config/vax/nbsdaout.mh b/gdb/config/vax/nbsdaout.mh
new file mode 100644 (file)
index 0000000..6887135
--- /dev/null
@@ -0,0 +1,6 @@
+# Host: NetBSD/vax a.out
+NATDEPFILES= vaxbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o \
+       solib.o solib-sunos.o
+NAT_FILE= nm-nbsdaout.h
+
+LOADLIBES= -lkvm
diff --git a/gdb/config/vax/nbsdelf.mh b/gdb/config/vax/nbsdelf.mh
new file mode 100644 (file)
index 0000000..06dda18
--- /dev/null
@@ -0,0 +1,5 @@
+# Host: NetBSD/vax ELF
+NATDEPFILES= vaxbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-nbsd.h
+
+LOADLIBES= -lkvm
diff --git a/gdb/config/vax/nm-nbsdaout.h b/gdb/config/vax/nm-nbsdaout.h
new file mode 100644 (file)
index 0000000..02504f5
--- /dev/null
@@ -0,0 +1,30 @@
+/* Native-dependent definitions for NetBSD/vax a.out.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 NM_NBSDAOUT_H
+#define NM_NBSDAOUT_H
+
+#include "config/nm-nbsd.h"
+
+/* Get generic NetBSD a.out native definitions.  */
+#include "config/nm-nbsdaout.h"
+
+#endif /* nm-nbsdaout.h */
diff --git a/gdb/config/vax/obsd.mh b/gdb/config/vax/obsd.mh
new file mode 100644 (file)
index 0000000..416f2c6
--- /dev/null
@@ -0,0 +1,5 @@
+# Host: OpenBSD/vax
+NATDEPFILES= vaxbsd-nat.o bsd-kvm.o fork-child.o infptrace.o inftarg.o
+NAT_FILE= config/nm-bsd.h
+
+LOADLIBES= -lkvm
diff --git a/gdb/config/vax/vax.mh b/gdb/config/vax/vax.mh
new file mode 100644 (file)
index 0000000..341aa6b
--- /dev/null
@@ -0,0 +1,4 @@
+# Host: VAX running 4.2BSD or Ultrix
+NATDEPFILES= vax-nat.o fork-child.o infptrace.o inftarg.o \
+       corelow.o core-aout.o
+NAT_FILE= nm-vax.h
diff --git a/gdb/gdb_ptrace.h b/gdb/gdb_ptrace.h
new file mode 100644 (file)
index 0000000..62a9949
--- /dev/null
@@ -0,0 +1,114 @@
+/* Portable <sys/ptrace.h>
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 GDB_PTRACE_H
+#define GDB_PTRACE_H
+
+/* The <sys/ptrace.h> header was introduced with 4.4BSD, and provided
+   the PT_* symbolic constants for the ptrace(2) request numbers.  The
+   ptrace(2) prototype was added later to the same header on BSD.
+   SunOS and GNU/Linux have slightly different symbolic names for the
+   constants that start with PTRACE_*.  System V still doesn't have
+   (and probably never will have) a <sys/ptrace.h> with symbolic
+   constants; the ptrace(2) prototype can be found in <unistd.h>.
+   Fortunately all systems use the same numerical constants for the
+   common ptrace requests.  */
+
+#ifdef HAVE_PTRACE_H
+# include <ptrace.h>
+#elif defined(HAVE_SYS_PTRACE_H)
+# include <sys/ptrace.h>
+#endif
+
+/* No need to include <unistd.h> since it's already included by
+   "defs.h".  */
+
+#ifndef PT_READ_I
+# define PT_READ_I     1       /* Read word in child's I space.  */
+#endif
+
+#ifndef PT_READ_D
+# define PT_READ_D     2       /* Read word in child's D space.  */
+#endif
+
+#ifndef PT_READ_U
+# define PT_READ_U     3       /* Read word in child's U space.  */
+#endif
+
+#ifndef PT_WRITE_I
+# define PT_WRITE_I    4       /* Write word in child's I space.  */
+#endif
+
+#ifndef PT_WRITE_D
+# define PT_WRITE_D    5       /* Write word in child's D space.  */
+#endif
+
+#ifndef PT_WRITE_U
+# define PT_WRITE_U    6       /* Write word in child's U space.  */
+#endif
+
+/* HP-UX doesn't define PT_CONTINUE and PT_STEP.  Instead of those two
+   ptrace requests, it has PT_CONTIN, PT_CONTIN1, PT_SINGLE and
+   PT_SINGLE1.  PT_CONTIN1 and PT_SINGLE1 preserve pending signals,
+   which apparently is what is wanted by the HP-UX native code.  */
+
+#ifndef PT_CONTINUE
+# ifdef PT_CONTIN1
+#  define PT_CONTINUE  PT_CONTIN1
+# else
+#  define PT_CONTINUE  7       /* Continue the child.  */
+# endif
+#endif
+
+#ifndef PT_KILL
+# define PT_KILL       8       /* Kill the child process.  */
+#endif
+
+#ifndef PT_STEP
+# ifdef PT_SINGLE1
+#  define PT_STEP      PT_SINGLE1
+# else
+#  define PT_STEP      9       /* Single step the child.   */
+# endif
+#endif
+
+/* Not all systems support attaching and detaching.   */
+
+#ifndef PT_ATTCH
+# ifdef PTRACE_DETACH
+#  define PT_ATTACH PTRACE_ATTACH
+# endif
+#endif
+
+#ifndef PT_DETACH
+# ifdef PTRACE_DETACH
+#  define PT_DETACH PTRACE_DETACH
+# endif
+#endif
+
+/* Some systems, in particular DEC OSF/1, Digital Unix, Compaq Tru64
+   or whatever it's called these days, don't provide a prototype for
+   ptrace.  Provide one to silence compiler warnings.  */
+#ifndef HAVE_DECL_PTRACE
+extern PTRACE_TYPE_RET ptrace();
+#endif
+
+#endif /* gdb_ptrace.h */
diff --git a/gdb/hppa-linux-nat.c b/gdb/hppa-linux-nat.c
new file mode 100644 (file)
index 0000000..b6a4f20
--- /dev/null
@@ -0,0 +1,376 @@
+/* Functions specific to running GDB native on HPPA running GNU/Linux.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+#include "gdb_string.h"
+#include "inferior.h"
+
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,43)
+#include <asm/offset.h>
+#else
+#include <asm/offsets.h>
+#endif
+
+#include "hppa-tdep.h"
+
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
+/* These must match the order of the register names.
+
+   Some sort of lookup table is needed because the offsets associated
+   with the registers are all over the board.  */
+
+static const int u_offsets[] =
+  {
+    /* general registers */
+    -1,
+    PT_GR1,
+    PT_GR2,
+    PT_GR3,
+    PT_GR4,
+    PT_GR5,
+    PT_GR6,
+    PT_GR7,
+    PT_GR8,
+    PT_GR9,
+    PT_GR10,
+    PT_GR11,
+    PT_GR12,
+    PT_GR13,
+    PT_GR14,
+    PT_GR15,
+    PT_GR16,
+    PT_GR17,
+    PT_GR18,
+    PT_GR19,
+    PT_GR20,
+    PT_GR21,
+    PT_GR22,
+    PT_GR23,
+    PT_GR24,
+    PT_GR25,
+    PT_GR26,
+    PT_GR27,
+    PT_GR28,
+    PT_GR29,
+    PT_GR30,
+    PT_GR31,
+
+    PT_SAR,
+    PT_IAOQ0,
+    PT_IASQ0,
+    PT_IAOQ1,
+    PT_IASQ1,
+    -1, /* eiem */
+    PT_IIR,
+    PT_ISR,
+    PT_IOR,
+    PT_PSW,
+    -1, /* goto */
+
+    PT_SR4,
+    PT_SR0,
+    PT_SR1,
+    PT_SR2,
+    PT_SR3,
+    PT_SR5,
+    PT_SR6,
+    PT_SR7,
+
+    -1, /* cr0 */
+    -1, /* pid0 */
+    -1, /* pid1 */
+    -1, /* ccr */
+    -1, /* pid2 */
+    -1, /* pid3 */
+    -1, /* cr24 */
+    -1, /* cr25 */
+    -1, /* cr26 */
+    PT_CR27,
+    -1, /* cr28 */
+    -1, /* cr29 */
+    -1, /* cr30 */
+
+    /* Floating point regs.  */
+    PT_FR0,  PT_FR0 + 4,
+    PT_FR1,  PT_FR1 + 4,
+    PT_FR2,  PT_FR2 + 4,
+    PT_FR3,  PT_FR3 + 4,
+    PT_FR4,  PT_FR4 + 4,
+    PT_FR5,  PT_FR5 + 4,
+    PT_FR6,  PT_FR6 + 4,
+    PT_FR7,  PT_FR7 + 4,
+    PT_FR8,  PT_FR8 + 4,
+    PT_FR9,  PT_FR9 + 4,
+    PT_FR10, PT_FR10 + 4,
+    PT_FR11, PT_FR11 + 4,
+    PT_FR12, PT_FR12 + 4,
+    PT_FR13, PT_FR13 + 4,
+    PT_FR14, PT_FR14 + 4,
+    PT_FR15, PT_FR15 + 4,
+    PT_FR16, PT_FR16 + 4,
+    PT_FR17, PT_FR17 + 4,
+    PT_FR18, PT_FR18 + 4,
+    PT_FR19, PT_FR19 + 4,
+    PT_FR20, PT_FR20 + 4,
+    PT_FR21, PT_FR21 + 4,
+    PT_FR22, PT_FR22 + 4,
+    PT_FR23, PT_FR23 + 4,
+    PT_FR24, PT_FR24 + 4,
+    PT_FR25, PT_FR25 + 4,
+    PT_FR26, PT_FR26 + 4,
+    PT_FR27, PT_FR27 + 4,
+    PT_FR28, PT_FR28 + 4,
+    PT_FR29, PT_FR29 + 4,
+    PT_FR30, PT_FR30 + 4,
+    PT_FR31, PT_FR31 + 4,
+  };
+
+CORE_ADDR
+register_addr (int regno, CORE_ADDR blockend)
+{
+  CORE_ADDR addr;
+
+  if ((unsigned) regno >= NUM_REGS)
+    error ("Invalid register number %d.", regno);
+
+  if (u_offsets[regno] == -1)
+    addr = 0;
+  else
+    {
+      addr = (CORE_ADDR) u_offsets[regno];
+    }
+
+  return addr;
+}
+
+/*
+ * Registers saved in a coredump:
+ * gr0..gr31
+ * sr0..sr7
+ * iaoq0..iaoq1
+ * iasq0..iasq1
+ * sar, iir, isr, ior, ipsw
+ * cr0, cr24..cr31
+ * cr8,9,12,13
+ * cr10, cr15
+ */
+#define GR_REGNUM(_n)  (HPPA_R0_REGNUM+_n)
+#define TR_REGNUM(_n)  (HPPA_TR0_REGNUM+_n)
+static const int greg_map[] =
+  {
+    GR_REGNUM(0), GR_REGNUM(1), GR_REGNUM(2), GR_REGNUM(3),
+    GR_REGNUM(4), GR_REGNUM(5), GR_REGNUM(6), GR_REGNUM(7),
+    GR_REGNUM(8), GR_REGNUM(9), GR_REGNUM(10), GR_REGNUM(11),
+    GR_REGNUM(12), GR_REGNUM(13), GR_REGNUM(14), GR_REGNUM(15),
+    GR_REGNUM(16), GR_REGNUM(17), GR_REGNUM(18), GR_REGNUM(19),
+    GR_REGNUM(20), GR_REGNUM(21), GR_REGNUM(22), GR_REGNUM(23),
+    GR_REGNUM(24), GR_REGNUM(25), GR_REGNUM(26), GR_REGNUM(27),
+    GR_REGNUM(28), GR_REGNUM(29), GR_REGNUM(30), GR_REGNUM(31),
+
+    HPPA_SR4_REGNUM+1, HPPA_SR4_REGNUM+2, HPPA_SR4_REGNUM+3, HPPA_SR4_REGNUM+4,
+    HPPA_SR4_REGNUM, HPPA_SR4_REGNUM+5, HPPA_SR4_REGNUM+6, HPPA_SR4_REGNUM+7,
+
+    HPPA_PCOQ_HEAD_REGNUM, HPPA_PCOQ_TAIL_REGNUM,
+    HPPA_PCSQ_HEAD_REGNUM, HPPA_PCSQ_TAIL_REGNUM,
+
+    HPPA_SAR_REGNUM, HPPA_IIR_REGNUM, HPPA_ISR_REGNUM, HPPA_IOR_REGNUM,
+    HPPA_IPSW_REGNUM, HPPA_RCR_REGNUM,
+
+    TR_REGNUM(0), TR_REGNUM(1), TR_REGNUM(2), TR_REGNUM(3),
+    TR_REGNUM(4), TR_REGNUM(5), TR_REGNUM(6), TR_REGNUM(7),
+
+    HPPA_PID0_REGNUM, HPPA_PID1_REGNUM, HPPA_PID2_REGNUM, HPPA_PID3_REGNUM,
+    HPPA_CCR_REGNUM, HPPA_EIEM_REGNUM,
+  };
+
+
+
+/* Fetch one register.  */
+
+static void
+fetch_register (int regno)
+{
+  int tid;
+  int val;
+
+  if (CANNOT_FETCH_REGISTER (regno))
+    {
+      regcache_raw_supply (current_regcache, regno, NULL);
+      return;
+    }
+
+  /* GNU/Linux LWP ID's are process ID's.  */
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
+
+  errno = 0;
+  val = ptrace (PTRACE_PEEKUSER, tid, register_addr (regno, 0), 0);
+  if (errno != 0)
+    error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regno),
+          regno, safe_strerror (errno));
+
+  regcache_raw_supply (current_regcache, regno, &val);
+}
+
+/* Store one register. */
+
+static void
+store_register (int regno)
+{
+  int tid;
+  int val;
+
+  if (CANNOT_STORE_REGISTER (regno))
+    return;
+
+  /* GNU/Linux LWP ID's are process ID's.  */
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
+
+  errno = 0;
+  regcache_raw_collect (current_regcache, regno, &val);
+  ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val);
+  if (errno != 0)
+    error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regno),
+          regno, safe_strerror (errno));
+}
+
+/* Fetch registers from the child process.  Fetch all registers if
+   regno == -1, otherwise fetch all general registers or all floating
+   point registers depending upon the value of regno.  */
+
+void
+fetch_inferior_registers (int regno)
+{
+  if (-1 == regno)
+    {
+      for (regno = 0; regno < NUM_REGS; regno++)
+        fetch_register (regno);
+    }
+  else 
+    {
+      fetch_register (regno);
+    }
+}
+
+/* Store registers back into the inferior.  Store all registers if
+   regno == -1, otherwise store all general registers or all floating
+   point registers depending upon the value of regno.  */
+
+void
+store_inferior_registers (int regno)
+{
+  if (-1 == regno)
+    {
+      for (regno = 0; regno < NUM_REGS; regno++)
+       store_register (regno);
+    }
+  else
+    {
+      store_register (regno);
+    }
+}
+
+/* Fill GDB's register array with the general-purpose register values
+   in *gregsetp.  */
+
+void
+supply_gregset (gdb_gregset_t *gregsetp)
+{
+  int i;
+  greg_t *regp = (elf_greg_t *) gregsetp;
+
+  for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++)
+    {
+      int regno = greg_map[i];
+      regcache_raw_supply (current_regcache, regno, regp);
+    }
+}
+
+/* Fill register regno (if it is a general-purpose register) in
+   *gregsetp with the appropriate value from GDB's register array.
+   If regno is -1, do this for all registers.  */
+
+void
+fill_gregset (gdb_gregset_t *gregsetp, int regno)
+{
+  int i;
+
+  for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++)
+    {
+      int mregno = greg_map[i];
+
+      if (regno == -1 || regno == mregno)
+       {
+          regcache_raw_collect(current_regcache, mregno, &(*gregsetp)[i]);
+       }
+    }
+}
+
+/*  Given a pointer to a floating point register set in /proc format
+   (fpregset_t *), unpack the register contents and supply them as gdb's
+   idea of the current floating point register values. */
+
+void
+supply_fpregset (gdb_fpregset_t *fpregsetp)
+{
+  int regi;
+  char *from;
+
+  for (regi = 0; regi <= 31; regi++)
+    {
+      from = (char *) &((*fpregsetp)[regi]);
+      regcache_raw_supply (current_regcache, 2*regi + HPPA_FP0_REGNUM, from);
+      regcache_raw_supply (current_regcache, 2*regi + HPPA_FP0_REGNUM + 1,
+                          from + 4);
+    }
+}
+
+/*  Given a pointer to a floating point register set in /proc format
+   (fpregset_t *), update the register specified by REGNO from gdb's idea
+   of the current floating point register set.  If REGNO is -1, update
+   them all. */
+
+void
+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
+{
+  int i;
+
+  for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32 * 2; i++)
+   {
+      /* Gross.  fpregset_t is double, registers[x] has single
+        precision reg.  */
+      char *to = (char *) &((*fpregsetp)[(i - HPPA_FP0_REGNUM) / 2]);
+      if ((i - HPPA_FP0_REGNUM) & 1)
+       to += 4;
+      regcache_raw_collect (current_regcache, i, to);
+   }
+}
diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c
new file mode 100644 (file)
index 0000000..7f32236
--- /dev/null
@@ -0,0 +1,592 @@
+/* Target-dependent code for GNU/Linux running on PA-RISC, for GDB.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+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.  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "target.h"
+#include "objfiles.h"
+#include "solib-svr4.h"
+#include "glibc-tdep.h"
+#include "frame-unwind.h"
+#include "trad-frame.h"
+#include "dwarf2-frame.h"
+#include "value.h"
+#include "hppa-tdep.h"
+
+#include "elf/common.h"
+
+#if 0
+/* Convert DWARF register number REG to the appropriate register
+   number used by GDB.  */
+static int
+hppa_dwarf_reg_to_regnum (int reg)
+{
+  /* registers 0 - 31 are the same in both sets */
+  if (reg < 32)
+    return reg;
+
+  /* dwarf regs 32 to 85 are fpregs 4 - 31 */
+  if (reg >= 32 && reg <= 85)
+    return HPPA_FP4_REGNUM + (reg - 32);
+
+  warning ("Unmapped DWARF Register #%d encountered\n", reg);
+  return -1;
+}
+#endif
+
+static void
+hppa_linux_target_write_pc (CORE_ADDR v, ptid_t ptid)
+{
+  /* Probably this should be done by the kernel, but it isn't.  */
+  write_register_pid (HPPA_PCOQ_HEAD_REGNUM, v | 0x3, ptid);
+  write_register_pid (HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3, ptid);
+}
+
+/* An instruction to match.  */
+struct insn_pattern
+{
+  unsigned int data;            /* See if it matches this....  */
+  unsigned int mask;            /* ... with this mask.  */
+};
+
+/* See bfd/elf32-hppa.c */
+static struct insn_pattern hppa_long_branch_stub[] = {
+  /* ldil LR'xxx,%r1 */
+  { 0x20200000, 0xffe00000 },
+  /* be,n RR'xxx(%sr4,%r1) */
+  { 0xe0202002, 0xffe02002 }, 
+  { 0, 0 }
+};
+
+static struct insn_pattern hppa_long_branch_pic_stub[] = {
+  /* b,l .+8, %r1 */
+  { 0xe8200000, 0xffe00000 },
+  /* addil LR'xxx - ($PIC_pcrel$0 - 4), %r1 */
+  { 0x28200000, 0xffe00000 },
+  /* be,n RR'xxxx - ($PIC_pcrel$0 - 8)(%sr4, %r1) */
+  { 0xe0202002, 0xffe02002 }, 
+  { 0, 0 }
+};
+
+static struct insn_pattern hppa_import_stub[] = {
+  /* addil LR'xxx, %dp */
+  { 0x2b600000, 0xffe00000 },
+  /* ldw RR'xxx(%r1), %r21 */
+  { 0x48350000, 0xffffb000 },
+  /* bv %r0(%r21) */
+  { 0xeaa0c000, 0xffffffff },
+  /* ldw RR'xxx+4(%r1), %r19 */
+  { 0x48330000, 0xffffb000 },
+  { 0, 0 }
+};
+
+static struct insn_pattern hppa_import_pic_stub[] = {
+  /* addil LR'xxx,%r19 */
+  { 0x2a600000, 0xffe00000 },
+  /* ldw RR'xxx(%r1),%r21 */
+  { 0x48350000, 0xffffb000 },
+  /* bv %r0(%r21) */
+  { 0xeaa0c000, 0xffffffff },
+  /* ldw RR'xxx+4(%r1),%r19 */
+  { 0x48330000, 0xffffb000 },
+  { 0, 0 },
+};
+
+static struct insn_pattern hppa_plt_stub[] = {
+  /* b,l 1b, %r20 - 1b is 3 insns before here */
+  { 0xea9f1fdd, 0xffffffff },
+  /* depi 0,31,2,%r20 */
+  { 0xd6801c1e, 0xffffffff },
+  { 0, 0 }
+};
+
+static struct insn_pattern hppa_sigtramp[] = {
+  /* ldi 0, %r25 or ldi 1, %r25 */
+  { 0x34190000, 0xfffffffd },
+  /* ldi __NR_rt_sigreturn, %r20 */
+  { 0x3414015a, 0xffffffff },
+  /* be,l 0x100(%sr2, %r0), %sr0, %r31 */
+  { 0xe4008200, 0xffffffff },
+  /* nop */
+  { 0x08000240, 0xffffffff },
+  { 0, 0 }
+};
+
+#define HPPA_MAX_INSN_PATTERN_LEN (4)
+
+/* Return non-zero if the instructions at PC match the series
+   described in PATTERN, or zero otherwise.  PATTERN is an array of
+   'struct insn_pattern' objects, terminated by an entry whose mask is
+   zero.
+
+   When the match is successful, fill INSN[i] with what PATTERN[i]
+   matched.  */
+static int
+insns_match_pattern (CORE_ADDR pc,
+                     struct insn_pattern *pattern,
+                     unsigned int *insn)
+{
+  int i;
+  CORE_ADDR npc = pc;
+
+  for (i = 0; pattern[i].mask; i++)
+    {
+      char buf[4];
+
+      deprecated_read_memory_nobpt (npc, buf, 4);
+      insn[i] = extract_unsigned_integer (buf, 4);
+      if ((insn[i] & pattern[i].mask) == pattern[i].data)
+        npc += 4;
+      else
+        return 0;
+    }
+  return 1;
+}
+
+static int
+hppa_linux_in_dyncall (CORE_ADDR pc)
+{
+  return pc == hppa_symbol_address("$$dyncall");
+}
+
+/* There are several kinds of "trampolines" that we need to deal with:
+   - long branch stubs: these are inserted by the linker when a branch
+     target is too far away for a branch insn to reach
+   - plt stubs: these should go into the .plt section, so are easy to find
+   - import stubs: used to call from object to shared lib or shared lib to 
+     shared lib; these go in regular text sections.  In fact the linker tries
+     to put them throughout the code because branches have limited reachability.
+     We use the same mechanism as ppc64 to recognize the stub insn patterns.
+   - $$dyncall: similar to hpux, hppa-linux uses $$dyncall for indirect function
+     calls. $$dyncall is exported by libgcc.a  */
+static int
+hppa_linux_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+  unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN];
+  int r;
+
+  r = in_plt_section (pc, name)
+      || hppa_linux_in_dyncall (pc)
+      || insns_match_pattern (pc, hppa_import_stub, insn)
+      || insns_match_pattern (pc, hppa_import_pic_stub, insn)
+      || insns_match_pattern (pc, hppa_long_branch_stub, insn)
+      || insns_match_pattern (pc, hppa_long_branch_pic_stub, insn);
+
+  return r;
+}
+
+static CORE_ADDR
+hppa_linux_skip_trampoline_code (CORE_ADDR pc)
+{
+  unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN];
+  int dp_rel, pic_rel;
+
+  /* dyncall handles both PLABELs and direct addresses */
+  if (hppa_linux_in_dyncall (pc))
+    {
+      pc = (CORE_ADDR) read_register (22);
+
+      /* PLABELs have bit 30 set; if it's a PLABEL, then dereference it */
+      if (pc & 0x2)
+       pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
+
+      return pc;
+    }
+
+  dp_rel = pic_rel = 0;
+  if ((dp_rel = insns_match_pattern (pc, hppa_import_stub, insn))
+      || (pic_rel = insns_match_pattern (pc, hppa_import_pic_stub, insn)))
+    {
+      /* Extract the target address from the addil/ldw sequence.  */
+      pc = hppa_extract_21 (insn[0]) + hppa_extract_14 (insn[1]);
+
+      if (dp_rel)
+        pc += (CORE_ADDR) read_register (27);
+      else
+        pc += (CORE_ADDR) read_register (19);
+
+      /* fallthrough */
+    }
+
+  if (in_plt_section (pc, NULL))
+    {
+      pc = (CORE_ADDR) read_memory_integer (pc, TARGET_PTR_BIT / 8);
+
+      /* if the plt slot has not yet been resolved, the target will
+         be the plt stub */
+      if (in_plt_section (pc, NULL))
+       {
+         /* Sanity check: are we pointing to the plt stub? */
+         if (insns_match_pattern (pc, hppa_plt_stub, insn))
+           {
+             /* this should point to the fixup routine */
+             pc = (CORE_ADDR) read_memory_integer (pc + 8, TARGET_PTR_BIT / 8);
+           }
+         else
+           {
+             error ("Cannot resolve plt stub at 0x%s\n",
+                    paddr_nz (pc));
+             pc = 0;
+           }
+       }
+    }
+
+  return pc;
+}
+
+/* Signal frames.  */
+
+/* (This is derived from MD_FALLBACK_FRAME_STATE_FOR in gcc.)
+   Unfortunately, because of various bugs and changes to the kernel,
+   we have several cases to deal with.
+
+   In 2.4, the signal trampoline is 4 bytes, and pc should point directly at 
+   the beginning of the trampoline and struct rt_sigframe.
+
+   In <= 2.6.5-rc2-pa3, the signal trampoline is 9 bytes, and pc points at
+   the 4th word in the trampoline structure.  This is wrong, it should point 
+   at the 5th word.  This is fixed in 2.6.5-rc2-pa4.
+
+   To detect these cases, we first take pc, align it to 64-bytes
+   to get the beginning of the signal frame, and then check offsets 0, 4
+   and 5 to see if we found the beginning of the trampoline.  This will
+   tell us how to locate the sigcontext structure.
+
+   Note that with a 2.4 64-bit kernel, the signal context is not properly
+   passed back to userspace so the unwind will not work correctly.  */
+static CORE_ADDR
+hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
+{
+  unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
+  int offs = 0;
+  int try;
+  /* offsets to try to find the trampoline */
+  static int pcoffs[] = { 0, 4*4, 5*4 };
+  /* offsets to the rt_sigframe structure */
+  static int sfoffs[] = { 4*4, 10*4, 10*4 };
+  CORE_ADDR sp;
+
+  /* Most of the time, this will be correct.  The one case when this will
+     fail is if the user defined an alternate stack, in which case the
+     beginning of the stack will not be align_down (pc, 64).  */
+  sp = align_down (pc, 64);
+
+  /* rt_sigreturn trampoline:
+     3419000x ldi 0, %r25 or ldi 1, %r25   (x = 0 or 2)
+     3414015a ldi __NR_rt_sigreturn, %r20 
+     e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
+     08000240 nop  */
+
+  for (try = 0; try < ARRAY_SIZE (pcoffs); try++)
+    {
+      if (insns_match_pattern (sp + pcoffs[try], hppa_sigtramp, dummy))
+       {
+          offs = sfoffs[try];
+         break;
+       }
+    }
+
+  if (offs == 0)
+    {
+      if (insns_match_pattern (pc, hppa_sigtramp, dummy))
+       {
+         /* sigaltstack case: we have no way of knowing which offset to 
+            use in this case; default to new kernel handling. If this is
+            wrong the unwinding will fail.  */
+         try = 2;
+         sp = pc - pcoffs[try];
+       }
+      else
+      {
+        return 0;
+      }
+    }
+
+  /* sp + sfoffs[try] points to a struct rt_sigframe, which contains
+     a struct siginfo and a struct ucontext.  struct ucontext contains
+     a struct sigcontext. Return an offset to this sigcontext here.  Too 
+     bad we cannot include system specific headers :-(.  
+     sizeof(struct siginfo) == 128
+     offsetof(struct ucontext, uc_mcontext) == 24.  */
+  return sp + sfoffs[try] + 128 + 24;
+}
+
+struct hppa_linux_sigtramp_unwind_cache
+{
+  CORE_ADDR base;
+  struct trad_frame_saved_reg *saved_regs;
+};
+
+static struct hppa_linux_sigtramp_unwind_cache *
+hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
+                                       void **this_cache)
+{
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct hppa_linux_sigtramp_unwind_cache *info;
+  CORE_ADDR pc, scptr;
+  int i;
+
+  if (*this_cache)
+    return *this_cache;
+
+  info = FRAME_OBSTACK_ZALLOC (struct hppa_linux_sigtramp_unwind_cache);
+  *this_cache = info;
+  info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+
+  pc = frame_pc_unwind (next_frame);
+  scptr = hppa_linux_sigtramp_find_sigcontext (pc);
+
+  /* structure of struct sigcontext:
+   
+     struct sigcontext {
+       unsigned long sc_flags;
+       unsigned long sc_gr[32]; 
+       unsigned long long sc_fr[32];
+       unsigned long sc_iasq[2];
+       unsigned long sc_iaoq[2];
+       unsigned long sc_sar;           */
+
+  /* Skip sc_flags.  */
+  scptr += 4;
+
+  /* GR[0] is the psw, we don't restore that.  */
+  scptr += 4;
+
+  /* General registers.  */
+  for (i = 1; i < 32; i++)
+    {
+      info->saved_regs[HPPA_R0_REGNUM + i].addr = scptr;
+      scptr += 4;
+    }
+
+  /* Pad.  */
+  scptr += 4;
+
+  /* FP regs; FP0-3 are not restored.  */
+  scptr += (8 * 4);
+
+  for (i = 4; i < 32; i++)
+    {
+      info->saved_regs[HPPA_FP0_REGNUM + (i * 2)].addr = scptr;
+      scptr += 4;
+      info->saved_regs[HPPA_FP0_REGNUM + (i * 2) + 1].addr = scptr;
+      scptr += 4;
+    }
+
+  /* IASQ/IAOQ. */
+  info->saved_regs[HPPA_PCSQ_HEAD_REGNUM].addr = scptr;
+  scptr += 4;
+  info->saved_regs[HPPA_PCSQ_TAIL_REGNUM].addr = scptr;
+  scptr += 4;
+
+  info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].addr = scptr;
+  scptr += 4;
+  info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
+  scptr += 4;
+
+  info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
+
+  return info;
+}
+
+static void
+hppa_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
+                                  void **this_prologue_cache,
+                                  struct frame_id *this_id)
+{
+  struct hppa_linux_sigtramp_unwind_cache *info
+    = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
+  *this_id = frame_id_build (info->base, frame_pc_unwind (next_frame));
+}
+
+static void
+hppa_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
+                                        void **this_prologue_cache,
+                                        int regnum, int *optimizedp,
+                                        enum lval_type *lvalp, 
+                                        CORE_ADDR *addrp,
+                                        int *realnump, void *valuep)
+{
+  struct hppa_linux_sigtramp_unwind_cache *info
+    = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
+  hppa_frame_prev_register_helper (next_frame, info->saved_regs, regnum,
+                                  optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
+  SIGTRAMP_FRAME,
+  hppa_linux_sigtramp_frame_this_id,
+  hppa_linux_sigtramp_frame_prev_register
+};
+
+/* hppa-linux always uses "new-style" rt-signals.  The signal handler's return
+   address should point to a signal trampoline on the stack.  The signal
+   trampoline is embedded in a rt_sigframe structure that is aligned on
+   the stack.  We take advantage of the fact that sp must be 64-byte aligned,
+   and the trampoline is small, so by rounding down the trampoline address
+   we can find the beginning of the struct rt_sigframe.  */
+static const struct frame_unwind *
+hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
+{
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
+
+  if (hppa_linux_sigtramp_find_sigcontext (pc))
+    return &hppa_linux_sigtramp_frame_unwind;
+
+  return NULL;
+}
+
+/* Attempt to find (and return) the global pointer for the given
+   function.
+
+   This is a rather nasty bit of code searchs for the .dynamic section
+   in the objfile corresponding to the pc of the function we're trying
+   to call.  Once it finds the addresses at which the .dynamic section
+   lives in the child process, it scans the Elf32_Dyn entries for a
+   DT_PLTGOT tag.  If it finds one of these, the corresponding
+   d_un.d_ptr value is the global pointer.  */
+
+static CORE_ADDR
+hppa_linux_find_global_pointer (struct value *function)
+{
+  struct obj_section *faddr_sect;
+  CORE_ADDR faddr;
+  
+  faddr = value_as_address (function);
+
+  /* Is this a plabel? If so, dereference it to get the gp value.  */
+  if (faddr & 2)
+    {
+      int status;
+      char buf[4];
+
+      faddr &= ~3;
+
+      status = target_read_memory (faddr + 4, buf, sizeof (buf));
+      if (status == 0)
+       return extract_unsigned_integer (buf, sizeof (buf));
+    }
+
+  /* If the address is in the plt section, then the real function hasn't 
+     yet been fixed up by the linker so we cannot determine the gp of 
+     that function.  */
+  if (in_plt_section (faddr, NULL))
+    return 0;
+
+  faddr_sect = find_pc_section (faddr);
+  if (faddr_sect != NULL)
+    {
+      struct obj_section *osect;
+
+      ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
+       {
+         if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
+           break;
+       }
+
+      if (osect < faddr_sect->objfile->sections_end)
+       {
+         CORE_ADDR addr;
+
+         addr = osect->addr;
+         while (addr < osect->endaddr)
+           {
+             int status;
+             LONGEST tag;
+             char buf[4];
+
+             status = target_read_memory (addr, buf, sizeof (buf));
+             if (status != 0)
+               break;
+             tag = extract_signed_integer (buf, sizeof (buf));
+
+             if (tag == DT_PLTGOT)
+               {
+                 CORE_ADDR global_pointer;
+
+                 status = target_read_memory (addr + 4, buf, sizeof (buf));
+                 if (status != 0)
+                   break;
+                 global_pointer = extract_unsigned_integer (buf, sizeof (buf));
+
+                 /* The payoff... */
+                 return global_pointer;
+               }
+
+             if (tag == DT_NULL)
+               break;
+
+             addr += 8;
+           }
+       }
+    }
+  return 0;
+}
+
+/* Forward declarations.  */
+extern initialize_file_ftype _initialize_hppa_linux_tdep;
+
+static void
+hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* GNU/Linux is always ELF.  */
+  tdep->is_elf = 1;
+
+  tdep->find_global_pointer = hppa_linux_find_global_pointer;
+
+  set_gdbarch_write_pc (gdbarch, hppa_linux_target_write_pc);
+
+  frame_unwind_append_sniffer (gdbarch, hppa_linux_sigtramp_unwind_sniffer);
+
+  /* GNU/Linux uses SVR4-style shared libraries.  */
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  set_gdbarch_in_solib_call_trampoline
+        (gdbarch, hppa_linux_in_solib_call_trampoline);
+  set_gdbarch_skip_trampoline_code
+       (gdbarch, hppa_linux_skip_trampoline_code);
+
+  /* GNU/Linux uses the dynamic linker included in the GNU C Library.  */
+  set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
+
+  /* On hppa-linux, currently, sizeof(long double) == 8.  There has been
+     some discussions to support 128-bit long double, but it requires some
+     more work in gcc and glibc first.  */
+  set_gdbarch_long_double_bit (gdbarch, 64);
+
+#if 0
+  /* Dwarf-2 unwinding support.  Not yet working.  */
+  set_gdbarch_dwarf_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
+  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
+#endif
+}
+
+void
+_initialize_hppa_linux_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_LINUX, hppa_linux_init_abi);
+}
diff --git a/gdb/hppabsd-nat.c b/gdb/hppabsd-nat.c
new file mode 100644 (file)
index 0000000..fb53c96
--- /dev/null
@@ -0,0 +1,119 @@
+/* Native-dependent code for HP PA-RISC BSD's.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "hppa-tdep.h"
+
+static int
+hppabsd_gregset_supplies_p (int regnum)
+{
+  return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_PCOQ_TAIL_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
+
+static void
+hppabsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+  const char *regs = gregs;
+  int regnum;
+
+  for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++)
+    regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+
+  regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
+  regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+  regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+   in GREGS.  */
+
+static void
+hppabsd_collect_gregset (const struct regcache *regcache,
+                         void *gregs, int regnum)
+{
+  char *regs = gregs;
+  int i;
+
+  for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
+    {
+      if (regnum == -1 || regnum == i)
+       regcache_raw_collect (regcache, i, regs + i * 4);
+    }
+
+  if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+    regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
+  if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+    regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+  if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+    regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+\f
+
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers (including the floating-point registers).  */
+
+void
+fetch_inferior_registers (int regnum)
+{
+  struct regcache *regcache = current_regcache;
+
+  if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
+    {
+      struct reg regs;
+
+      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+       perror_with_name ("Couldn't get registers");
+
+      hppabsd_supply_gregset (regcache, &regs);
+    }
+}
+
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers (including the floating-point registers).  */
+
+void
+store_inferior_registers (int regnum)
+{
+  if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
+    {
+      struct reg regs;
+
+      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+        perror_with_name ("Couldn't get registers");
+
+      hppabsd_collect_gregset (current_regcache, &regs, regnum);
+
+      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+        perror_with_name ("Couldn't write registers");
+    }
+}
diff --git a/gdb/hppabsd-tdep.c b/gdb/hppabsd-tdep.c
new file mode 100644 (file)
index 0000000..0a54371
--- /dev/null
@@ -0,0 +1,137 @@
+/* Target-dependent code for HP PA-RISC BSD's.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "hppa-tdep.h"
+#include "solib-svr4.h"
+
+/* Core file support.  */
+
+/* Sizeof `struct reg' in <machine/reg.h>.  */
+#define HPPABSD_SIZEOF_GREGS   (34 * 4)
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+   in the general-purpose register set REGSET to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+
+static void
+hppabsd_supply_gregset (const struct regset *regset, struct regcache *regcache,
+                    int regnum, const void *gregs, size_t len)
+{
+  const char *regs = gregs;
+  size_t offset;
+  int i;
+
+  gdb_assert (len >= HPPABSD_SIZEOF_GREGS);
+
+  for (i = HPPA_R1_REGNUM, offset = 4; i <= HPPA_R31_REGNUM; i++, offset += 4)
+    {
+      if (regnum == -1 || regnum == i)
+       regcache_raw_supply (regcache, i, regs + offset);
+    }
+
+  if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+    regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs);
+  if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+    regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+  if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+    regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+
+/* OpenBSD/hppa register set.  */
+
+static struct regset hppabsd_gregset =
+{
+  NULL,
+  hppabsd_supply_gregset
+};
+
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+static const struct regset *
+hppabsd_regset_from_core_section (struct gdbarch *gdbarch,
+                                 const char *sect_name, size_t sect_size)
+{
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= HPPABSD_SIZEOF_GREGS)
+    return &hppabsd_gregset;
+
+  return NULL;
+}
+\f
+
+static void
+hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Core file support.  */
+  set_gdbarch_regset_from_core_section
+    (gdbarch, hppabsd_regset_from_core_section);
+
+  /* OpenBSD and NetBSD use ELF.  */
+  tdep->is_elf = 1;
+
+  /* OpenBSD and NetBSD uses SVR4-style shared libraries.  */
+  set_gdbarch_in_solib_call_trampoline
+    (gdbarch, generic_in_solib_call_trampoline);
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+/* OpenBSD uses uses the traditional NetBSD core file format, even for
+   ports that use ELF.  */
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+
+static enum gdb_osabi
+hppabsd_core_osabi_sniffer (bfd *abfd)
+{
+  if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+    return GDB_OSABI_NETBSD_CORE;
+
+  return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_hppabsd_tdep (void);
+
+void
+_initialize_hppabsd_tdep (void)
+{
+  /* BFD doesn't set a flavour for NetBSD style a.out core files.  */
+  gdbarch_register_osabi_sniffer (bfd_arch_hppa, bfd_target_unknown_flavour,
+                                 hppabsd_core_osabi_sniffer);
+
+  gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF,
+                         hppabsd_init_abi);
+  gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD_ELF,
+                         hppabsd_init_abi);
+}
diff --git a/gdb/i386nbsd-nat.c b/gdb/i386nbsd-nat.c
new file mode 100644 (file)
index 0000000..92da7e1
--- /dev/null
@@ -0,0 +1,82 @@
+/* Native-dependent code for NetBSD/i386.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "regcache.h"
+
+#include "i386-tdep.h"
+
+/* Support for debugging kernel virtual memory images.  */
+
+#include <sys/types.h>
+#include <machine/frame.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+  struct switchframe sf;
+
+  /* The following is true for NetBSD 1.6.2:
+
+     The pcb contains %esp and %ebp at the point of the context switch
+     in cpu_switch().  At that point we have a stack frame as
+     described by `struct switchframe', which for NetBSD 1.6.2 has the
+     following layout:
+
+     interrupt level
+     %edi
+     %esi
+     %ebx
+     %eip
+
+     we reconstruct the register state as it would look when we just
+     returned from cpu_switch().  */
+
+  /* The stack pointer shouldn't be zero.  */
+  if (pcb->pcb_esp == 0)
+    return 0;
+
+  read_memory (pcb->pcb_esp, (char *) &sf, sizeof sf);
+  pcb->pcb_esp += sizeof (struct switchframe);
+  regcache_raw_supply (regcache, I386_EDI_REGNUM, &sf.sf_edi);
+  regcache_raw_supply (regcache, I386_ESI_REGNUM, &sf.sf_esi);
+  regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
+  regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
+  regcache_raw_supply (regcache, I386_EBX_REGNUM, &sf.sf_ebx);
+  regcache_raw_supply (regcache, I386_EIP_REGNUM, &sf.sf_eip);
+
+  return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_i386nbsd_nat (void);
+
+void
+_initialize_i386nbsd_nat (void)
+{
+  /* Support debugging kernel virtual memory images.  */
+  bsd_kvm_add_target (i386nbsd_supply_pcb);
+}
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
new file mode 100644 (file)
index 0000000..f729611
--- /dev/null
@@ -0,0 +1,241 @@
+/* Default child (native) target interface, for GDB when running under
+   Unix.
+
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "regcache.h"
+#include "memattr.h"
+#include "symtab.h"
+#include "target.h"
+#include "inferior.h"
+
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers.  */
+
+static void
+inf_child_fetch_inferior_registers (int regnum)
+{
+  if (regnum == -1)
+    {
+      for (regnum = 0; regnum < NUM_REGS; regnum++)
+       regcache_raw_supply (current_regcache, regnum, NULL);
+    }
+  else
+    regcache_raw_supply (current_regcache, regnum, NULL);
+}
+
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers (including the floating point registers).  */
+
+static void
+inf_child_store_inferior_registers (int regnum)
+{
+}
+
+void
+inf_child_post_wait (ptid_t ptid, int wait_status)
+{
+  /* This version of Unix doesn't require a meaningful "post wait"
+     operation.
+   */
+}
+
+static void
+inf_child_post_attach (int pid)
+{
+  /* This version of Unix doesn't require a meaningful "post attach"
+     operation by a debugger.  */
+}
+
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On
+   machines which store all the registers in one fell swoop, this
+   makes sure that registers contains all the registers from the
+   program being debugged.  */
+
+static void
+inf_child_prepare_to_store (void)
+{
+}
+
+static void
+inf_child_open (char *arg, int from_tty)
+{
+  error ("Use the \"run\" command to start a Unix child process.");
+}
+
+static void
+inf_child_post_startup_inferior (ptid_t ptid)
+{
+  /* This version of Unix doesn't require a meaningful "post startup
+     inferior" operation by a debugger.  */
+}
+
+static void
+inf_child_acknowledge_created_inferior (int pid)
+{
+  /* This version of Unix doesn't require a meaningful "acknowledge
+     created inferior" operation by a debugger.  */
+}
+
+static int
+inf_child_insert_fork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of fork
+     events.  */
+  return 0;
+}
+
+static int
+inf_child_remove_fork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of fork
+     events.  */
+  return 0;
+}
+
+static int
+inf_child_insert_vfork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of vfork
+     events.  */
+  return 0;
+}
+
+static int
+inf_child_remove_vfork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of vfork
+     events.  */
+  return 0;
+}
+
+static int
+inf_child_follow_fork (int follow_child)
+{
+  /* This version of Unix doesn't support following fork or vfork
+     events.  */
+  return 0;
+}
+
+static int
+inf_child_insert_exec_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of exec
+     events.  */
+  return 0;
+}
+
+static int
+inf_child_remove_exec_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of exec
+     events.  */
+  return 0;
+}
+
+static int
+inf_child_reported_exec_events_per_exec_call (void)
+{
+  /* This version of Unix doesn't support notification of exec
+     events.  */
+  return 1;
+}
+
+static int
+inf_child_can_run (void)
+{
+  return 1;
+}
+
+static struct symtab_and_line *
+inf_child_enable_exception_callback (enum exception_event_kind kind,
+                                    int enable)
+{
+  return (struct symtab_and_line *) NULL;
+}
+
+static struct exception_event_record *
+inf_child_get_current_exception_event (void)
+{
+  return (struct exception_event_record *) NULL;
+}
+
+static char *
+inf_child_pid_to_exec_file (int pid)
+{
+  /* This version of Unix doesn't support translation of a process ID
+     to the filename of the executable file.  */
+  return NULL;
+}
+
+static char *
+inf_child_core_file_to_sym_file (char *core)
+{
+  /* The target stratum for a running executable need not support this
+     operation.  */
+  return NULL;
+}
+
+struct target_ops *
+inf_child_target (void)
+{
+  struct target_ops *t = XZALLOC (struct target_ops);
+  t->to_shortname = "child";
+  t->to_longname = "Unix child process";
+  t->to_doc = "Unix child process (started by the \"run\" command).";
+  t->to_open = inf_child_open;
+  t->to_post_attach = inf_child_post_attach;
+  t->to_post_wait = inf_child_post_wait;
+  t->to_prepare_to_store = inf_child_prepare_to_store;
+  t->to_insert_breakpoint = memory_insert_breakpoint;
+  t->to_remove_breakpoint = memory_remove_breakpoint;
+  t->to_terminal_init = terminal_init_inferior;
+  t->to_terminal_inferior = terminal_inferior;
+  t->to_terminal_ours_for_output = terminal_ours_for_output;
+  t->to_terminal_save_ours = terminal_save_ours;
+  t->to_terminal_ours = terminal_ours;
+  t->to_terminal_info = child_terminal_info;
+  t->to_post_startup_inferior = inf_child_post_startup_inferior;
+  t->to_acknowledge_created_inferior = inf_child_acknowledge_created_inferior;
+  t->to_insert_fork_catchpoint = inf_child_insert_fork_catchpoint;
+  t->to_remove_fork_catchpoint = inf_child_remove_fork_catchpoint;
+  t->to_insert_vfork_catchpoint = inf_child_insert_vfork_catchpoint;
+  t->to_remove_vfork_catchpoint = inf_child_remove_vfork_catchpoint;
+  t->to_follow_fork = inf_child_follow_fork;
+  t->to_insert_exec_catchpoint = inf_child_insert_exec_catchpoint;
+  t->to_remove_exec_catchpoint = inf_child_remove_exec_catchpoint;
+  t->to_reported_exec_events_per_exec_call =
+    inf_child_reported_exec_events_per_exec_call;
+  t->to_can_run = inf_child_can_run;
+  t->to_enable_exception_callback = inf_child_enable_exception_callback;
+  t->to_get_current_exception_event = inf_child_get_current_exception_event;
+  t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
+  t->to_stratum = process_stratum;
+  t->to_has_all_memory = 1;
+  t->to_has_memory = 1;
+  t->to_has_stack = 1;
+  t->to_has_registers = 1;
+  t->to_has_execution = 1;
+  t->to_magic = OPS_MAGIC;
+  return t;
+}
diff --git a/gdb/inf-child.h b/gdb/inf-child.h
new file mode 100644 (file)
index 0000000..5b6edec
--- /dev/null
@@ -0,0 +1,30 @@
+/* Low level Unix child interface, for GDB when running under Unix.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 INF_CHILD_H
+#define INF_CHILD_H
+
+/* Create a prototype child target.  The client can override it with
+   local methods.  */
+
+extern struct target_ops *inf_child_target (void);
+
+#endif
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
new file mode 100644 (file)
index 0000000..f79f786
--- /dev/null
@@ -0,0 +1,685 @@
+/* Low level Unix child interface to ptrace, for GDB when running under Unix.
+
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "observer.h"
+#include "gdb_ptrace.h"
+#include "inflow.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "command.h"
+#include "gdbcore.h"
+#include "inf-child.h"
+#include "gdbcmd.h"
+
+#include <sys/wait.h>
+#include <signal.h>
+
+/* HACK: Save the ptrace ops returned by ptrace_target.  */
+static struct target_ops *ptrace_ops_hack;
+
+static void
+inf_ptrace_kill_inferior (void)
+{
+  int status;
+  int pid = PIDGET (inferior_ptid);
+
+  if (pid == 0)
+    return;
+
+  /* This once used to call "kill" to kill the inferior just in case
+     the inferior was still running.  As others have noted in the past
+     (kingdon) there shouldn't be any way to get here if the inferior
+     is still running -- else there's a major problem elsewere in gdb
+     and it needs to be fixed.
+
+     The kill call causes problems under hpux10, so it's been removed;
+     if this causes problems we'll deal with them as they arise.  */
+  call_ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3) 0, 0);
+  ptrace_wait (null_ptid, &status);
+  target_mourn_inferior ();
+}
+
+/* Resume execution of the inferior process.  If STEP is nonzero,
+   single-step it.  If SIGNAL is nonzero, give it that signal.  */
+
+static void
+inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
+{
+  int request = PT_CONTINUE;
+  int pid = PIDGET (ptid);
+
+  if (pid == -1)
+    /* Resume all threads.  */
+    /* I think this only gets used in the non-threaded case, where
+       "resume all threads" and "resume inferior_ptid" are the
+       same.  */
+    pid = PIDGET (inferior_ptid);
+
+  if (step)
+    {
+      /* If this system does not support PT_STEP, a higher level
+         function will have called single_step() to transmute the step
+         request into a continue request (by setting breakpoints on
+         all possible successor instructions), so we don't have to
+         worry about that here.  */
+      request = PT_STEP;
+    }
+
+  /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
+     where it was.  If GDB wanted it to start some other way, we have
+     already written a new PC value to the child.  */
+  errno = 0;
+  ptrace (request, pid, (PTRACE_TYPE_ARG3) 1, target_signal_to_host (signal));
+  if (errno != 0)
+    perror_with_name ("ptrace");
+}
+
+/* Set an upper limit on alloca.  */
+#define GDB_MAX_ALLOCA 0x1000
+
+/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
+   in the NEW_SUN_PTRACE case.  It ought to be straightforward.  But
+   it appears that writing did not write the data that I specified.  I
+   cannot understand where it got the data that it actually did
+   write.  */
+
+/* Copy LEN bytes to or from inferior's memory starting at MEMADDR to
+   debugger memory starting at MYADDR.  Copy to inferior if WRITE is
+   nonzero.  TARGET is ignored.
+
+   Returns the length copied, which is either the LEN argument or
+   zero.  This xfer function does not do partial moves, since
+   ptrace_ops_hack doesn't allow memory operations to cross below us in the
+   target stack anyway.  */
+
+int
+inf_ptrace_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                       struct mem_attrib *attrib, struct target_ops *target)
+{
+  int i;
+  /* Round starting address down to longword boundary.  */
+  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
+  /* Round ending address up; get number of longwords that makes.  */
+  int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
+              / sizeof (PTRACE_TYPE_RET));
+  int alloc = count * sizeof (PTRACE_TYPE_RET);
+  PTRACE_TYPE_RET *buffer;
+  struct cleanup *old_chain = NULL;
+
+#ifdef PT_IO
+  /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO request
+     that promises to be much more efficient in reading and writing
+     data in the traced process's address space.  */
+
+  {
+    struct ptrace_io_desc piod;
+
+    /* NOTE: We assume that there are no distinct address spaces for
+       instruction and data.  */
+    piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D;
+    piod.piod_offs = (void *) memaddr;
+    piod.piod_addr = myaddr;
+    piod.piod_len = len;
+
+    if (ptrace (PT_IO, PIDGET (inferior_ptid), (caddr_t) & piod, 0) == -1)
+      {
+       /* If the PT_IO request is somehow not supported, fallback on
+          using PT_WRITE_D/PT_READ_D.  Otherwise we will return zero
+          to indicate failure.  */
+       if (errno != EINVAL)
+         return 0;
+      }
+    else
+      {
+       /* Return the actual number of bytes read or written.  */
+       return piod.piod_len;
+      }
+  }
+#endif
+
+  /* Allocate buffer of that many longwords.  */
+  if (len < GDB_MAX_ALLOCA)
+    {
+      buffer = (PTRACE_TYPE_RET *) alloca (alloc);
+    }
+  else
+    {
+      buffer = (PTRACE_TYPE_RET *) xmalloc (alloc);
+      old_chain = make_cleanup (xfree, buffer);
+    }
+
+  if (write)
+    {
+      /* Fill start and end extra bytes of buffer with existing memory
+         data.  */
+      if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
+       {
+         /* Need part of initial word -- fetch it.  */
+         buffer[0] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
+                             (PTRACE_TYPE_ARG3) addr, 0);
+       }
+
+      if (count > 1)           /* FIXME, avoid if even boundary.  */
+       {
+         buffer[count - 1] =
+           ptrace (PT_READ_I, PIDGET (inferior_ptid),
+                   ((PTRACE_TYPE_ARG3)
+                    (addr + (count - 1) * sizeof (PTRACE_TYPE_RET))), 0);
+       }
+
+      /* Copy data to be written over corresponding part of buffer.  */
+      memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
+             myaddr, len);
+
+      /* Write the entire buffer.  */
+      for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
+       {
+         errno = 0;
+         ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) addr, buffer[i]);
+         if (errno)
+           {
+             /* Using the appropriate one (I or D) is necessary for
+                Gould NP1, at least.  */
+             errno = 0;
+             ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
+                     (PTRACE_TYPE_ARG3) addr, buffer[i]);
+           }
+         if (errno)
+           return 0;
+       }
+    }
+  else
+    {
+      /* Read all the longwords.  */
+      for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
+       {
+         errno = 0;
+         buffer[i] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
+                             (PTRACE_TYPE_ARG3) addr, 0);
+         if (errno)
+           return 0;
+         QUIT;
+       }
+
+      /* Copy appropriate bytes out of the buffer.  */
+      memcpy (myaddr,
+             (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
+             len);
+    }
+
+  if (old_chain != NULL)
+    do_cleanups (old_chain);
+  return len;
+}
+
+/* Wait for child to do something.  Return pid of child, or -1 in case
+   of error; store status through argument pointer OURSTATUS.  */
+
+static ptid_t
+inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+{
+  int save_errno;
+  int status;
+  char *execd_pathname = NULL;
+  int exit_status;
+  int related_pid;
+  int syscall_id;
+  enum target_waitkind kind;
+  int pid;
+
+  do
+    {
+      set_sigint_trap ();      /* Causes SIGINT to be passed on to the
+                                  attached process. */
+      set_sigio_trap ();
+
+      pid = ptrace_wait (inferior_ptid, &status);
+
+      save_errno = errno;
+
+      clear_sigio_trap ();
+
+      clear_sigint_trap ();
+
+      if (pid == -1)
+       {
+         if (save_errno == EINTR)
+           continue;
+
+         fprintf_unfiltered (gdb_stderr,
+                             "Child process unexpectedly missing: %s.\n",
+                             safe_strerror (save_errno));
+
+         /* Claim it exited with unknown signal.  */
+         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+         ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+         return pid_to_ptid (-1);
+       }
+
+      /* Did it exit?
+       */
+      if (target_has_exited (pid, status, &exit_status))
+       {
+         /* ??rehrauer: For now, ignore this. */
+         continue;
+       }
+
+      if (!target_thread_alive (pid_to_ptid (pid)))
+       {
+         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+         return pid_to_ptid (pid);
+       }
+    }
+  while (pid != PIDGET (inferior_ptid));       /* Some other child died or stopped */
+
+  store_waitstatus (ourstatus, status);
+  return pid_to_ptid (pid);
+}
+
+void
+inf_ptrace_post_wait (ptid_t ptid, int wait_status)
+{
+  /* This version of Unix doesn't require a meaningful "post wait"
+     operation.
+   */
+}
+
+/* Check to see if the given thread is alive.
+
+   FIXME: Is kill() ever the right way to do this?  I doubt it, but
+   for now we're going to try and be compatable with the old thread
+   code.  */
+
+static int
+inf_ptrace_thread_alive (ptid_t ptid)
+{
+  pid_t pid = PIDGET (ptid);
+
+  return (kill (pid, 0) != -1);
+}
+
+/* Attach to process PID, then initialize for debugging it.  */
+
+static void
+inf_ptrace_attach (char *args, int from_tty)
+{
+  char *exec_file;
+  int pid;
+  char *dummy;
+
+  if (!args)
+    error_no_arg ("process-id to attach");
+
+  dummy = args;
+  pid = strtol (args, &dummy, 0);
+  /* Some targets don't set errno on errors, grrr! */
+  if ((pid == 0) && (args == dummy))
+    error ("Illegal process-id: %s\n", args);
+
+  if (pid == getpid ())                /* Trying to masturbate? */
+    error ("I refuse to debug myself!");
+
+  if (from_tty)
+    {
+      exec_file = (char *) get_exec_file (0);
+
+      if (exec_file)
+       printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
+                          target_pid_to_str (pid_to_ptid (pid)));
+      else
+       printf_unfiltered ("Attaching to %s\n",
+                          target_pid_to_str (pid_to_ptid (pid)));
+
+      gdb_flush (gdb_stdout);
+    }
+
+  attach (pid);
+
+  inferior_ptid = pid_to_ptid (pid);
+  push_target (ptrace_ops_hack);
+}
+
+static void
+inf_ptrace_post_attach (int pid)
+{
+  /* This version of Unix doesn't require a meaningful "post attach"
+     operation by a debugger.  */
+}
+
+/* Take a program previously attached to and detaches it.  The program
+   resumes execution and will no longer stop on signals, etc.  We'd
+   better not have left any breakpoints in the program or it'll die
+   when it hits one.  For this to work, it may be necessary for the
+   process to have been previously attached.  It *might* work if the
+   program was started via the normal ptrace (PTRACE_TRACEME).  */
+
+static void
+inf_ptrace_detach (char *args, int from_tty)
+{
+  int siggnal = 0;
+  int pid = PIDGET (inferior_ptid);
+
+  if (from_tty)
+    {
+      char *exec_file = get_exec_file (0);
+      if (exec_file == 0)
+       exec_file = "";
+      printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
+                        target_pid_to_str (pid_to_ptid (pid)));
+      gdb_flush (gdb_stdout);
+    }
+  if (args)
+    siggnal = atoi (args);
+
+  detach (siggnal);
+
+  inferior_ptid = null_ptid;
+  unpush_target (ptrace_ops_hack);
+}
+
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On
+   machines which store all the registers in one fell swoop, this
+   makes sure that registers contains all the registers from the
+   program being debugged.  */
+
+static void
+inf_ptrace_prepare_to_store (void)
+{
+}
+
+/* Print status information about what we're accessing.  */
+
+static void
+inf_ptrace_files_info (struct target_ops *ignore)
+{
+  printf_unfiltered ("\tUsing the running image of %s %s.\n",
+                    attach_flag ? "attached" : "child",
+                    target_pid_to_str (inferior_ptid));
+}
+
+static void
+inf_ptrace_open (char *arg, int from_tty)
+{
+  error ("Use the \"run\" command to start a Unix child process.");
+}
+
+/* Stub function which causes the inferior that runs it, to be ptrace-able
+   by its parent process.  */
+
+static void
+inf_ptrace_me (void)
+{
+  /* "Trace me, Dr. Memory!" */
+  call_ptrace (0, 0, (PTRACE_TYPE_ARG3) 0, 0);
+}
+
+/* Stub function which causes the GDB that runs it, to start ptrace-ing
+   the child process.  */
+
+static void
+inf_ptrace_him (int pid)
+{
+  push_target (ptrace_ops_hack);
+
+  /* On some targets, there must be some explicit synchronization
+     between the parent and child processes after the debugger
+     forks, and before the child execs the debuggee program.  This
+     call basically gives permission for the child to exec.
+   */
+
+  target_acknowledge_created_inferior (pid);
+
+  /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
+   * and will be 1 or 2 depending on whether we're starting
+   * without or with a shell.
+   */
+  startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
+
+  /* On some targets, there must be some explicit actions taken after
+     the inferior has been started up.
+   */
+  target_post_startup_inferior (pid_to_ptid (pid));
+}
+
+/* Start an inferior Unix child process and sets inferior_ptid to its
+   pid.  EXEC_FILE is the file to run.  ALLARGS is a string containing
+   the arguments to the program.  ENV is the environment vector to
+   pass.  Errors reported with error().  */
+
+static void
+inf_ptrace_create_inferior (char *exec_file, char *allargs, char **env,
+                           int from_tty)
+{
+  fork_inferior (exec_file, allargs, env, inf_ptrace_me, inf_ptrace_him,
+                NULL, NULL);
+  /* We are at the first instruction we care about.  */
+  observer_notify_inferior_created (&current_target, from_tty);
+  /* Pedal to the metal... */
+  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+}
+
+static void
+inf_ptrace_post_startup_inferior (ptid_t ptid)
+{
+  /* This version of Unix doesn't require a meaningful "post startup inferior"
+     operation by a debugger.
+   */
+}
+
+static void
+inf_ptrace_acknowledge_created_inferior (int pid)
+{
+  /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
+     operation by a debugger.
+   */
+}
+
+static int
+inf_ptrace_insert_fork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of fork events.  */
+  return 0;
+}
+
+static int
+inf_ptrace_remove_fork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of fork events.  */
+  return 0;
+}
+
+static int
+inf_ptrace_insert_vfork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of vfork events.  */
+  return 0;
+}
+
+static int
+inf_ptrace_remove_vfork_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of vfork events.  */
+  return 0;
+}
+
+static int
+inf_ptrace_follow_fork (int follow_child)
+{
+  /* This version of Unix doesn't support following fork or vfork events.  */
+  return 0;
+}
+
+static int
+inf_ptrace_insert_exec_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of exec events.  */
+  return 0;
+}
+
+static int
+inf_ptrace_remove_exec_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of exec events.  */
+  return 0;
+}
+
+static int
+inf_ptrace_reported_exec_events_per_exec_call (void)
+{
+  /* This version of Unix doesn't support notification of exec events.
+   */
+  return 1;
+}
+
+static int
+inf_ptrace_has_exited (int pid, int wait_status, int *exit_status)
+{
+  if (WIFEXITED (wait_status))
+    {
+      *exit_status = WEXITSTATUS (wait_status);
+      return 1;
+    }
+
+  if (WIFSIGNALED (wait_status))
+    {
+      *exit_status = 0;                /* ?? Don't know what else to say here. */
+      return 1;
+    }
+
+  /* ?? Do we really need to consult the event state, too?  Assume the
+     wait_state alone suffices.
+   */
+  return 0;
+}
+
+static void
+inf_ptrace_mourn_inferior (void)
+{
+  unpush_target (ptrace_ops_hack);
+  generic_mourn_inferior ();
+}
+
+static int
+inf_ptrace_can_run (void)
+{
+  return 1;
+}
+
+/* Send a SIGINT to the process group.  This acts just like the user
+   typed a ^C on the controlling terminal.
+
+   XXX - This may not be correct for all systems.  Some may want to
+   use killpg() instead of kill (-pgrp). */
+
+static void
+inf_ptrace_stop (void)
+{
+  kill (-inferior_process_group, SIGINT);
+}
+
+/* Perform a partial transfer to/from the specified object.  For
+   memory transfers, fall back to the old memory xfer functions.  */
+
+static LONGEST
+inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
+                        const char *annex, void *readbuf,
+                        const void *writebuf, ULONGEST offset, LONGEST len)
+{
+  switch (object)
+    {
+    case TARGET_OBJECT_MEMORY:
+      if (readbuf)
+       return inf_ptrace_xfer_memory (offset, readbuf, len, 0 /*write */ ,
+                                      NULL, ops);
+      if (writebuf)
+       return inf_ptrace_xfer_memory (offset, readbuf, len, 1 /*write */ ,
+                                      NULL, ops);
+      return -1;
+
+    case TARGET_OBJECT_UNWIND_TABLE:
+      return -1;
+
+    case TARGET_OBJECT_AUXV:
+      return -1;
+
+    case TARGET_OBJECT_WCOOKIE:
+      return -1;
+
+    default:
+      return -1;
+    }
+}
+
+static char *
+inf_ptrace_pid_to_str (ptid_t ptid)
+{
+  return normal_pid_to_str (ptid);
+}
+
+struct target_ops *
+inf_ptrace_target (void)
+{
+  struct target_ops *t = inf_child_target ();
+  t->to_open = inf_ptrace_open;
+  t->to_attach = inf_ptrace_attach;
+  t->to_post_attach = inf_ptrace_post_attach;
+  t->to_detach = inf_ptrace_detach;
+  t->to_resume = inf_ptrace_resume;
+  t->to_wait = inf_ptrace_wait;
+  t->to_post_wait = inf_ptrace_post_wait;
+  t->to_prepare_to_store = inf_ptrace_prepare_to_store;
+  t->to_xfer_memory = inf_ptrace_xfer_memory;
+  t->to_xfer_partial = inf_ptrace_xfer_partial;
+  t->to_files_info = inf_ptrace_files_info;
+  t->to_kill = inf_ptrace_kill_inferior;
+  t->to_create_inferior = inf_ptrace_create_inferior;
+  t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
+  t->to_acknowledge_created_inferior =
+    inf_ptrace_acknowledge_created_inferior;
+  t->to_insert_fork_catchpoint = inf_ptrace_insert_fork_catchpoint;
+  t->to_remove_fork_catchpoint = inf_ptrace_remove_fork_catchpoint;
+  t->to_insert_vfork_catchpoint = inf_ptrace_insert_vfork_catchpoint;
+  t->to_remove_vfork_catchpoint = inf_ptrace_remove_vfork_catchpoint;
+  t->to_follow_fork = inf_ptrace_follow_fork;
+  t->to_insert_exec_catchpoint = inf_ptrace_insert_exec_catchpoint;
+  t->to_remove_exec_catchpoint = inf_ptrace_remove_exec_catchpoint;
+  t->to_reported_exec_events_per_exec_call =
+    inf_ptrace_reported_exec_events_per_exec_call;
+  t->to_has_exited = inf_ptrace_has_exited;
+  t->to_mourn_inferior = inf_ptrace_mourn_inferior;
+  t->to_can_run = inf_ptrace_can_run;
+  t->to_thread_alive = inf_ptrace_thread_alive;
+  t->to_pid_to_str = inf_ptrace_pid_to_str;
+  t->to_stop = inf_ptrace_stop;
+  t->to_stratum = process_stratum;
+  t->to_has_all_memory = 1;
+  t->to_has_memory = 1;
+  t->to_has_stack = 1;
+  t->to_has_registers = 1;
+  t->to_has_execution = 1;
+  t->to_magic = OPS_MAGIC;
+  ptrace_ops_hack = t;
+  return t;
+}
diff --git a/gdb/inf-ptrace.h b/gdb/inf-ptrace.h
new file mode 100644 (file)
index 0000000..e9ceae3
--- /dev/null
@@ -0,0 +1,31 @@
+/* Low level Unix child interface to ptrace, for GDB when running
+   under Unix.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 INF_PTRACE_H
+#define INF_PTRACE_H
+
+/* Create a prototype ptrace target.  The client can override it with
+   local methods.  */
+
+extern struct target_ops *inf_ptrace_target (void);
+
+#endif
diff --git a/gdb/m68kbsd-nat.c b/gdb/m68kbsd-nat.c
new file mode 100644 (file)
index 0000000..34e94b4
--- /dev/null
@@ -0,0 +1,228 @@
+/* Native-dependent code for Motorola 68000 BSD's.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "m68k-tdep.h"
+
+static int
+m68kbsd_gregset_supplies_p (int regnum)
+{
+  return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
+}
+
+static int
+m68kbsd_fpregset_supplies_p (int regnum)
+{
+  return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
+
+static void
+m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+  const char *regs = gregs;
+  int regnum;
+
+  for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
+    regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE.  */
+
+static void
+m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+{
+  const char *regs = fpregs;
+  int regnum;
+
+  for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
+    regcache_raw_supply (regcache, regnum,
+                        regs + m68kbsd_fpreg_offset (regnum));
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+   in GREGS.  */
+
+static void
+m68kbsd_collect_gregset (const struct regcache *regcache,
+                        void *gregs, int regnum)
+{
+  char *regs = gregs;
+  int i;
+
+  for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+    {
+      if (regnum == -1 || regnum == i)
+       regcache_raw_collect (regcache, i, regs + i * 4);
+    }
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+   in FPREGS.  */
+
+static void
+m68kbsd_collect_fpregset (struct regcache *regcache,
+                         void *fpregs, int regnum)
+{
+  char *regs = fpregs;
+  int i;
+
+  for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
+    {
+      if (regnum == -1 || regnum == i)
+       regcache_raw_collect (regcache, i, regs + m68kbsd_fpreg_offset (i));
+    }
+}
+\f
+
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers (including the floating-point registers).  */
+
+void
+fetch_inferior_registers (int regnum)
+{
+  if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+    {
+      struct reg regs;
+
+      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+       perror_with_name ("Couldn't get registers");
+
+      m68kbsd_supply_gregset (current_regcache, &regs);
+    }
+
+  if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+    {
+      struct fpreg fpregs;
+
+      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+       perror_with_name ("Couldn't get floating point status");
+
+      m68kbsd_supply_fpregset (current_regcache, &fpregs);
+    }
+}
+
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers (including the floating-point registers).  */
+
+void
+store_inferior_registers (int regnum)
+{
+  if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+    {
+      struct reg regs;
+
+      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+        perror_with_name ("Couldn't get registers");
+
+      m68kbsd_collect_gregset (current_regcache, &regs, regnum);
+
+      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+        perror_with_name ("Couldn't write registers");
+    }
+
+  if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+    {
+      struct fpreg fpregs;
+
+      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+       perror_with_name ("Couldn't get floating point status");
+
+      m68kbsd_collect_fpregset (current_regcache, &fpregs, regnum);
+
+      if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+       perror_with_name ("Couldn't write floating point status");
+    }
+}
+\f
+
+/* Support for debugging kernel virtual memory images.  */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+/* OpenBSD doesn't have these.  */
+#ifndef PCB_REGS_FP
+#define PCB_REGS_FP 10
+#endif
+#ifndef PCB_REGS_SP
+#define PCB_REGS_SP 11
+#endif
+
+static int
+m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+  int regnum, tmp;
+  int i = 0;
+
+  /* The following is true for NetBSD 1.6.2:
+
+     The pcb contains %d2...%d7, %a2...%a7 and %ps.  This accounts for
+     all callee-saved registers.  From this information we reconstruct
+     the register state as it would look when we just returned from
+     cpu_switch().  */
+
+  /* The stack pointer shouldn't be zero.  */
+  if (pcb->pcb_regs[PCB_REGS_SP] == 0)
+    return 0;
+
+  for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
+    regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+  for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
+    regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+
+  tmp = pcb->pcb_ps & 0xffff;
+  regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
+
+  read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
+  regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
+
+  return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_m68kbsd_nat (void);
+
+void
+_initialize_m68kbsd_nat (void)
+{
+  /* Support debugging kernel virtual memory images.  */
+  bsd_kvm_add_target (m68kbsd_supply_pcb);
+}
diff --git a/gdb/m68kbsd-tdep.c b/gdb/m68kbsd-tdep.c
new file mode 100644 (file)
index 0000000..4060668
--- /dev/null
@@ -0,0 +1,228 @@
+/* Target-dependent code for Motorola 68000 BSD's.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "m68k-tdep.h"
+#include "solib-svr4.h"
+
+/* Core file support.  */
+
+/* Sizeof `struct reg' in <machine/reg.h>.  */
+#define M68KBSD_SIZEOF_GREGS   (18 * 4)
+
+/* Sizeof `struct fpreg' in <machine/reg.h.  */
+#define M68KBSD_SIZEOF_FPREGS  (((8 * 3) + 3) * 4)
+
+int
+m68kbsd_fpreg_offset (int regnum)
+{
+  if (regnum >= M68K_FPC_REGNUM)
+    return 8 * 12 + (regnum - M68K_FPC_REGNUM) * 4;
+
+  return (regnum - M68K_FP0_REGNUM) * 12;
+}
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+   in the floating-point register set REGSET to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+
+static void
+m68kbsd_supply_fpregset (const struct regset *regset,
+                        struct regcache *regcache,
+                        int regnum, const void *fpregs, size_t len)
+{
+  const char *regs = fpregs;
+  int i;
+
+  gdb_assert (len >= M68KBSD_SIZEOF_FPREGS);
+
+  for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
+    {
+      if (regnum == i || regnum == -1)
+       regcache_raw_supply (regcache, i, regs + m68kbsd_fpreg_offset (i));
+    }
+}
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+   in the general-purpose register set REGSET to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+
+static void
+m68kbsd_supply_gregset (const struct regset *regset,
+                       struct regcache *regcache,
+                       int regnum, const void *gregs, size_t len)
+{
+  const char *regs = gregs;
+  int i;
+
+  gdb_assert (len >= M68KBSD_SIZEOF_GREGS);
+
+  for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+    {
+      if (regnum == i || regnum == -1)
+       regcache_raw_supply (regcache, i, regs + i * 4);
+    }
+
+  if (len >= M68KBSD_SIZEOF_GREGS + M68KBSD_SIZEOF_FPREGS)
+    {
+      regs += M68KBSD_SIZEOF_GREGS;
+      len -= M68KBSD_SIZEOF_GREGS;
+      m68kbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+    }
+}
+
+/* Motorola 68000 register sets.  */
+
+static struct regset m68kbsd_gregset =
+{
+  NULL,
+  m68kbsd_supply_gregset
+};
+
+static struct regset m68kbsd_fpregset =
+{
+  NULL,
+  m68kbsd_supply_fpregset
+};
+
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+static const struct regset *
+m68kbsd_regset_from_core_section (struct gdbarch *gdbarch,
+                                 const char *sect_name, size_t sect_size)
+{
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= M68KBSD_SIZEOF_GREGS)
+    return &m68kbsd_gregset;
+
+  if (strcmp (sect_name, ".reg2") == 0 && sect_size >= M68KBSD_SIZEOF_FPREGS)
+    return &m68kbsd_fpregset;
+
+  return NULL;
+}
+\f
+
+/* Support for shared libraries.  */
+
+/* Return non-zero if we are in a shared library trampoline code stub.  */
+
+int
+m68kbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+  return (name && !strcmp (name, "_DYNAMIC"));
+}
+\f
+
+static void
+m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  tdep->jb_pc = 5;
+  tdep->jb_elt_size = 4;
+
+  set_gdbarch_regset_from_core_section
+    (gdbarch, m68kbsd_regset_from_core_section);
+}
+
+/* OpenBSD and NetBSD a.out.  */
+
+static void
+m68kbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  m68kbsd_init_abi (info, gdbarch);
+
+  tdep->struct_return = reg_struct_return;
+
+  /* Assume SunOS-style shared libraries.  */
+  set_gdbarch_in_solib_call_trampoline
+    (gdbarch, m68kbsd_aout_in_solib_call_trampoline);
+}
+
+/* NetBSD ELF.  */
+
+static void
+m68kbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  m68kbsd_init_abi (info, gdbarch);
+
+  /* NetBSD ELF uses the SVR4 ABI.  */
+  m68k_svr4_init_abi (info, gdbarch);
+  tdep->struct_return = pcc_struct_return;
+
+  /* NetBSD ELF uses SVR4-style shared libraries.  */
+  set_gdbarch_in_solib_call_trampoline
+    (gdbarch, generic_in_solib_call_trampoline);
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+static enum gdb_osabi
+m68kbsd_aout_osabi_sniffer (bfd *abfd)
+{
+  if (strcmp (bfd_get_target (abfd), "a.out-m68k-netbsd") == 0
+      || strcmp (bfd_get_target (abfd), "a.out-m68k4k-netbsd") == 0)
+    return GDB_OSABI_NETBSD_AOUT;
+
+  return GDB_OSABI_UNKNOWN;
+}
+
+static enum gdb_osabi
+m68kbsd_core_osabi_sniffer (bfd *abfd)
+{
+  if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+    return GDB_OSABI_NETBSD_AOUT;
+
+  return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_m68kbsd_tdep (void);
+
+void
+_initialize_m68kbsd_tdep (void)
+{
+  gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
+                                 m68kbsd_aout_osabi_sniffer);
+
+  /* BFD doesn't set a flavour for NetBSD style a.out core files.  */
+  gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_unknown_flavour,
+                                 m68kbsd_core_osabi_sniffer);
+
+  gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_AOUT,
+                         m68kbsd_aout_init_abi);
+  gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
+                         m68kbsd_elf_init_abi);
+}
diff --git a/gdb/m88k-tdep.c b/gdb/m88k-tdep.c
new file mode 100644 (file)
index 0000000..7037808
--- /dev/null
@@ -0,0 +1,895 @@
+/* Target-dependent code for the Motorola 88000 series.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "dis-asm.h"
+#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "gdbtypes.h"
+#include "regcache.h"
+#include "regset.h"
+#include "symtab.h"
+#include "trad-frame.h"
+#include "value.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "m88k-tdep.h"
+
+/* Fetch the instruction at PC.  */
+
+static unsigned long
+m88k_fetch_instruction (CORE_ADDR pc)
+{
+  return read_memory_unsigned_integer (pc, 4);
+}
+
+/* Register information.  */
+
+/* Return the name of register REGNUM.  */
+
+static const char *
+m88k_register_name (int regnum)
+{
+  static char *register_names[] =
+  {
+    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+    "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
+    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+    "epsr", "fpsr", "fpcr", "sxip", "snip", "sfip"
+  };
+
+  if (regnum >= 0 && regnum < ARRAY_SIZE (register_names))
+    return register_names[regnum];
+
+  return NULL;
+}
+
+/* Return the GDB type object for the "standard" data type of data in
+   register REGNUM. */
+
+static struct type *
+m88k_register_type (struct gdbarch *gdbarch, int regnum)
+{
+  /* SXIP, SNIP, SFIP and R1 contain code addresses.  */
+  if ((regnum >= M88K_SXIP_REGNUM && regnum <= M88K_SFIP_REGNUM)
+      || regnum == M88K_R1_REGNUM)
+    return builtin_type_void_func_ptr;
+
+  /* R30 and R31 typically contains data addresses.  */
+  if (regnum == M88K_R30_REGNUM || regnum == M88K_R31_REGNUM)
+    return builtin_type_void_data_ptr;
+
+  return builtin_type_int32;
+}
+\f
+
+static CORE_ADDR
+m88k_addr_bits_remove (CORE_ADDR addr)
+{
+  /* All instructures are 4-byte aligned.  The lower 2 bits of SXIP,
+     SNIP and SFIP are used for special purposes: bit 0 is the
+     exception bit and bit 1 is the valid bit.  */
+  return addr & ~0x3;
+}
+
+/* Use the program counter to determine the contents and size of a
+   breakpoint instruction.  Return a pointer to a string of bytes that
+   encode a breakpoint instruction, store the length of the string in
+   *LEN and optionally adjust *PC to point to the correct memory
+   location for inserting the breakpoint.  */
+   
+static const unsigned char *
+m88k_breakpoint_from_pc (CORE_ADDR *pc, int *len)
+{
+  /* tb 0,r0,511 */
+  static unsigned char break_insn[] = { 0xf0, 0x00, 0xd1, 0xff };
+
+  *len = sizeof (break_insn);
+  return break_insn;
+}
+
+static CORE_ADDR
+m88k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  CORE_ADDR pc;
+
+  pc = frame_unwind_register_unsigned (next_frame, M88K_SXIP_REGNUM);
+  return m88k_addr_bits_remove (pc);
+}
+
+static void
+m88k_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+  /* According to the MC88100 RISC Microprocessor User's Manual,
+     section 6.4.3.1.2:
+
+     "... can be made to return to a particular instruction by placing
+     a valid instruction address in the SNIP and the next sequential
+     instruction address in the SFIP (with V bits set and E bits
+     clear).  The rte resumes execution at the instruction pointed to
+     by the SNIP, then the SFIP."
+
+     The E bit is the least significant bit (bit 0).  The V (valid)
+     bit is bit 1.  This is why we logical or 2 into the values we are
+     writing below.  It turns out that SXIP plays no role when
+     returning from an exception so nothing special has to be done
+     with it.  We could even (presumably) give it a totally bogus
+     value.  */
+
+  write_register_pid (M88K_SXIP_REGNUM, pc, ptid);
+  write_register_pid (M88K_SNIP_REGNUM, pc | 2, ptid);
+  write_register_pid (M88K_SFIP_REGNUM, (pc + 4) | 2, ptid);
+}
+\f
+
+/* The functions on this page are intended to be used to classify
+   function arguments.  */
+
+/* Check whether TYPE is "Integral or Pointer".  */
+
+static int
+m88k_integral_or_pointer_p (const struct type *type)
+{
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_INT:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_RANGE:
+      {
+       /* We have byte, half-word, word and extended-word/doubleword
+           integral types.  */
+       int len = TYPE_LENGTH (type);
+       return (len == 1 || len == 2 || len == 4 || len == 8);
+      }
+      return 1;
+    case TYPE_CODE_PTR:
+    case TYPE_CODE_REF:
+      {
+       /* Allow only 32-bit pointers.  */
+       return (TYPE_LENGTH (type) == 4);
+      }
+      return 1;
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+/* Check whether TYPE is "Floating".  */
+
+static int
+m88k_floating_p (const struct type *type)
+{
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_FLT:
+      {
+       int len = TYPE_LENGTH (type);
+       return (len == 4 || len == 8);
+      }
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+/* Check whether TYPE is "Structure or Union".  */
+
+static int
+m88k_structure_or_union_p (const struct type *type)
+{
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      return 1;
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+/* Check whether TYPE has 8-byte alignment.  */
+
+static int
+m88k_8_byte_align_p (struct type *type)
+{
+  if (m88k_structure_or_union_p (type))
+    {
+      int i;
+
+      for (i = 0; i < TYPE_NFIELDS (type); i++)
+       {
+         struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+
+         if (m88k_8_byte_align_p (subtype))
+           return 1;
+       }
+    }
+
+  if (m88k_integral_or_pointer_p (type) || m88k_floating_p (type))
+    return (TYPE_LENGTH (type) == 8);
+
+  return 0;
+}
+
+/* Check whether TYPE can be passed in a register.  */
+
+static int
+m88k_in_register_p (struct type *type)
+{
+  if (m88k_integral_or_pointer_p (type) || m88k_floating_p (type))
+    return 1;
+
+  if (m88k_structure_or_union_p (type) && TYPE_LENGTH (type) == 4)
+    return 1;
+
+  return 0;
+}
+
+static CORE_ADDR
+m88k_store_arguments (struct regcache *regcache, int nargs,
+                     struct value **args, CORE_ADDR sp)
+{
+  int num_register_words = 0;
+  int num_stack_words = 0;
+  int i;
+
+  for (i = 0; i < nargs; i++)
+    {
+      struct type *type = VALUE_TYPE (args[i]);
+      int len = TYPE_LENGTH (type);
+
+      if (m88k_integral_or_pointer_p (type) && len < 4)
+       {
+         args[i] = value_cast (builtin_type_int32, args[i]);
+         type = VALUE_TYPE (args[i]);
+         len = TYPE_LENGTH (type);
+       }
+
+      if (m88k_in_register_p (type))
+       {
+         int num_words = 0;
+
+         if (num_register_words % 2 == 1 && m88k_8_byte_align_p (type))
+           num_words++;
+
+         num_words += ((len + 3) / 4);
+         if (num_register_words + num_words <= 8)
+           {
+             num_register_words += num_words;
+             continue;
+           }
+
+         /* We've run out of available registers.  Pass the argument
+             on the stack.  */
+       }
+
+      if (num_stack_words % 2 == 1 && m88k_8_byte_align_p (type))
+       num_stack_words++;
+
+      num_stack_words += ((len + 3) / 4);
+    }
+
+  /* Allocate stack space.  */
+  sp = align_down (sp - 32 - num_stack_words * 4, 16);
+  num_stack_words = num_register_words = 0;
+
+  for (i = 0; i < nargs; i++)
+    {
+      char *valbuf = VALUE_CONTENTS (args[i]);
+      struct type *type = VALUE_TYPE (args[i]);
+      int len = TYPE_LENGTH (type);
+      int stack_word = num_stack_words;
+
+      if (m88k_in_register_p (type))
+       {
+         int register_word = num_register_words;
+
+         if (register_word % 2 == 1 && m88k_8_byte_align_p (type))
+           register_word++;
+
+         gdb_assert (len == 4 || len == 8);
+
+         if (register_word + len / 8 < 8)
+           {
+             int regnum = M88K_R2_REGNUM + register_word;
+
+             regcache_raw_write (regcache, regnum, valbuf);
+             if (len > 4)
+               regcache_raw_write (regcache, regnum + 1, valbuf + 4);
+
+             num_register_words = (register_word + len / 4);
+             continue;
+           }
+       }
+
+      if (stack_word % 2 == -1 && m88k_8_byte_align_p (type))
+       stack_word++;
+
+      write_memory (sp + stack_word * 4, valbuf, len);
+      num_stack_words = (stack_word + (len + 3) / 4);
+    }
+
+  return sp;
+}
+
+static CORE_ADDR
+m88k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+                     struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+                     struct value **args, CORE_ADDR sp, int struct_return,
+                     CORE_ADDR struct_addr)
+{
+  /* Set up the function arguments.  */
+  sp = m88k_store_arguments (regcache, nargs, args, sp);
+  gdb_assert (sp % 16 == 0);
+
+  /* Store return value address.  */
+  if (struct_return)
+    regcache_raw_write_unsigned (regcache, M88K_R12_REGNUM, struct_addr);
+
+  /* Store the stack pointer and return address in the appropriate
+     registers.  */
+  regcache_raw_write_unsigned (regcache, M88K_R31_REGNUM, sp);
+  regcache_raw_write_unsigned (regcache, M88K_R1_REGNUM, bp_addr);
+
+  /* Return the stack pointer.  */
+  return sp;
+}
+
+static struct frame_id
+m88k_unwind_dummy_id (struct gdbarch *arch, struct frame_info *next_frame)
+{
+  CORE_ADDR sp;
+
+  sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM);
+  return frame_id_build (sp, frame_pc_unwind (next_frame));
+}
+\f
+
+/* Determine, for architecture GDBARCH, how a return value of TYPE
+   should be returned.  If it is supposed to be returned in registers,
+   and READBUF is non-zero, read the appropriate value from REGCACHE,
+   and copy it into READBUF.  If WRITEBUF is non-zero, write the value
+   from WRITEBUF into REGCACHE.  */
+
+static enum return_value_convention
+m88k_return_value (struct gdbarch *gdbarch, struct type *type,
+                  struct regcache *regcache, void *readbuf,
+                  const void *writebuf)
+{
+  int len = TYPE_LENGTH (type);
+  char buf[8];
+
+  if (!m88k_integral_or_pointer_p (type) && !m88k_floating_p (type))
+    return RETURN_VALUE_STRUCT_CONVENTION;
+
+  if (readbuf)
+    {
+      /* Read the contents of R2 and (if necessary) R3.  */
+      regcache_cooked_read (regcache, M88K_R2_REGNUM, buf);
+      if (len > 4)
+       {
+         regcache_cooked_read (regcache, M88K_R3_REGNUM, buf + 4);
+         gdb_assert (len == 8);
+         memcpy (readbuf, buf, len);
+       }
+      else
+       {
+         /* Just stripping off any unused bytes should preserve the
+             signed-ness just fine.  */
+         memcpy (readbuf, buf + 4 - len, len);
+       }
+    }
+
+  if (writebuf)
+    {
+      /* Read the contents to R2 and (if necessary) R3.  */
+      if (len > 4)
+       {
+         gdb_assert (len == 8);
+         memcpy (buf, writebuf, 8);
+         regcache_cooked_write (regcache, M88K_R3_REGNUM, buf + 4);
+       }
+      else
+       {
+         /* ??? Do we need to do any sign-extension here?  */
+         memcpy (buf + 4 - len, writebuf, len);
+       }
+      regcache_cooked_write (regcache, M88K_R2_REGNUM, buf);
+    }
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+\f
+/* Default frame unwinder.  */
+
+struct m88k_frame_cache
+{
+  /* Base address.  */
+  CORE_ADDR base;
+  CORE_ADDR pc;
+
+  int sp_offset;
+  int fp_offset;
+
+  /* Table of saved registers.  */
+  struct trad_frame_saved_reg *saved_regs;
+};
+
+/* Prologue analysis.  */
+
+/* Macros for extracting fields from instructions.  */
+
+#define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos))
+#define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width))
+#define        SUBU_OFFSET(x)  ((unsigned)(x & 0xFFFF))
+#define        ST_OFFSET(x)    ((unsigned)((x) & 0xFFFF))
+#define        ST_SRC(x)       EXTRACT_FIELD ((x), 21, 5)
+#define        ADDU_OFFSET(x)  ((unsigned)(x & 0xFFFF))
+
+/* Possible actions to be taken by the prologue analyzer for the
+   instructions it encounters.  */
+
+enum m88k_prologue_insn_action
+{
+  M88K_PIA_SKIP,               /* Ignore.  */
+  M88K_PIA_NOTE_ST,            /* Note register store.  */
+  M88K_PIA_NOTE_STD,           /* Note register pair store.  */
+  M88K_PIA_NOTE_SP_ADJUSTMENT, /* Note stack pointer adjustment.  */
+  M88K_PIA_NOTE_FP_ASSIGNMENT, /* Note frame pointer assignment.  */
+  M88K_PIA_NOTE_BRANCH,                /* Note branch.  */
+  M88K_PIA_NOTE_PROLOGUE_END   /* Note end of prologue.  */
+};
+
+/* Table of instructions that may comprise a function prologue.  */
+
+struct m88k_prologue_insn
+{
+  unsigned long insn;
+  unsigned long mask;
+  enum m88k_prologue_insn_action action;
+};
+
+struct m88k_prologue_insn m88k_prologue_insn_table[] =
+{
+  /* Various register move instructions.  */
+  { 0x58000000, 0xf800ffff, M88K_PIA_SKIP },     /* or/or.u with immed of 0 */
+  { 0xf4005800, 0xfc1fffe0, M88K_PIA_SKIP },     /* or rd,r0,rs */
+  { 0xf4005800, 0xfc00ffff, M88K_PIA_SKIP },     /* or rd,rs,r0 */
+
+  /* Various other instructions.  */
+  { 0x58000000, 0xf8000000, M88K_PIA_SKIP },     /* or/or.u */
+
+  /* Stack pointer setup: "subu sp,sp,n" where n is a multiple of 8.  */
+  { 0x67ff0000, 0xffff0007, M88K_PIA_NOTE_SP_ADJUSTMENT },
+
+  /* Frame pointer assignment: "addu r30,r31,n".  */
+  { 0x63df0000, 0xffff0000, M88K_PIA_NOTE_FP_ASSIGNMENT },
+
+  /* Store to stack instructions; either "st rx,sp,n" or "st.d rx,sp,n".  */
+  { 0x241f0000, 0xfc1f0000, M88K_PIA_NOTE_ST },  /* st rx,sp,n */
+  { 0x201f0000, 0xfc1f0000, M88K_PIA_NOTE_STD }, /* st.d rs,sp,n */
+
+  /* Instructions needed for setting up r25 for pic code.  */
+  { 0x5f200000, 0xffff0000, M88K_PIA_SKIP },     /* or.u r25,r0,offset_high */
+  { 0xcc000002, 0xffffffff, M88K_PIA_SKIP },     /* bsr.n Lab */
+  { 0x5b390000, 0xffff0000, M88K_PIA_SKIP },     /* or r25,r25,offset_low */
+  { 0xf7396001, 0xffffffff, M88K_PIA_SKIP },     /* Lab: addu r25,r25,r1 */
+
+  /* Various branch or jump instructions which have a delay slot --
+     these do not form part of the prologue, but the instruction in
+     the delay slot might be a store instruction which should be
+     noted.  */
+  { 0xc4000000, 0xe4000000, M88K_PIA_NOTE_BRANCH },
+                                      /* br.n, bsr.n, bb0.n, or bb1.n */
+  { 0xec000000, 0xfc000000, M88K_PIA_NOTE_BRANCH }, /* bcnd.n */
+  { 0xf400c400, 0xfffff7e0, M88K_PIA_NOTE_BRANCH }, /* jmp.n or jsr.n */
+
+  /* Catch all.  Ends prologue analysis.  */
+  { 0x00000000, 0x00000000, M88K_PIA_NOTE_PROLOGUE_END }
+};
+
+/* Do a full analysis of the function prologue at PC and update CACHE
+   accordingly.  Bail out early if LIMIT is reached.  Return the
+   address where the analysis stopped.  If LIMIT points beyond the
+   function prologue, the return address should be the end of the
+   prologue.  */
+
+static CORE_ADDR
+m88k_analyze_prologue (CORE_ADDR pc, CORE_ADDR limit,
+                      struct m88k_frame_cache *cache)
+{
+  CORE_ADDR end = limit;
+
+  /* Provide a dummy cache if necessary.  */
+  if (cache == NULL)
+    {
+      size_t sizeof_saved_regs =
+       (M88K_R31_REGNUM + 1) * sizeof (struct trad_frame_saved_reg);
+
+      cache = alloca (sizeof (struct m88k_frame_cache));
+      cache->saved_regs = alloca (sizeof_saved_regs);
+
+      /* We only initialize the members we care about.  */
+      cache->saved_regs[M88K_R1_REGNUM].addr = -1;
+      cache->fp_offset = -1;
+    }
+
+  while (pc < limit)
+    {
+      struct m88k_prologue_insn *pi = m88k_prologue_insn_table;
+      unsigned long insn = m88k_fetch_instruction (pc);
+
+      while ((insn & pi->mask) != pi->insn)
+       pi++;
+
+      switch (pi->action)
+       {
+       case M88K_PIA_SKIP:
+         /* If we have a frame pointer, and R1 has been saved,
+             consider this instruction as not being part of the
+             prologue.  */
+         if (cache->fp_offset != -1
+             && cache->saved_regs[M88K_R1_REGNUM].addr != -1)
+           return min (pc, end);
+         break;
+
+       case M88K_PIA_NOTE_ST:
+       case M88K_PIA_NOTE_STD:
+         /* If no frame has been allocated, the stores aren't part of
+             the prologue.  */
+         if (cache->sp_offset == 0)
+           return min (pc, end);
+
+         /* Record location of saved registers.  */
+         {
+           int regnum = ST_SRC (insn) + M88K_R0_REGNUM;
+           ULONGEST offset = ST_OFFSET (insn);
+
+           cache->saved_regs[regnum].addr = offset;
+           if (pi->action == M88K_PIA_NOTE_STD && regnum < M88K_R31_REGNUM)
+             cache->saved_regs[regnum + 1].addr = offset + 4;
+         }
+         break;
+
+       case M88K_PIA_NOTE_SP_ADJUSTMENT:
+         /* A second stack pointer adjustment isn't part of the
+             prologue.  */
+         if (cache->sp_offset != 0)
+           return min (pc, end);
+
+         /* Store stack pointer adjustment.  */
+         cache->sp_offset = -SUBU_OFFSET (insn);
+         break;
+
+       case M88K_PIA_NOTE_FP_ASSIGNMENT:
+         /* A second frame pointer assignment isn't part of the
+             prologue.  */
+         if (cache->fp_offset != -1)
+           return min (pc, end);
+
+         /* Record frame pointer assignment.  */
+         cache->fp_offset = ADDU_OFFSET (insn);
+         break;
+
+       case M88K_PIA_NOTE_BRANCH:
+         /* The branch instruction isn't part of the prologue, but
+             the instruction in the delay slot might be.  Limit the
+             prologue analysis to the delay slot and record the branch
+             instruction as the end of the prologue.  */
+         limit = min (limit, pc + 2 * M88K_INSN_SIZE);
+         end = pc;
+         break;
+
+       case M88K_PIA_NOTE_PROLOGUE_END:
+         return min (pc, end);
+       }
+
+      pc += M88K_INSN_SIZE;
+    }
+
+  return end;
+}
+
+/* An upper limit to the size of the prologue.  */
+const int m88k_max_prologue_size = 128 * M88K_INSN_SIZE;
+
+/* Return the address of first real instruction of the function
+   starting at PC.  */
+
+static CORE_ADDR
+m88k_skip_prologue (CORE_ADDR pc)
+{
+  struct symtab_and_line sal;
+  CORE_ADDR func_start, func_end;
+
+  /* This is the preferred method, find the end of the prologue by
+     using the debugging information.  */
+  if (find_pc_partial_function (pc, NULL, &func_start, &func_end))
+    {
+      sal = find_pc_line (func_start, 0);
+
+      if (sal.end < func_end && pc <= sal.end)
+       return sal.end;
+    }
+
+  return m88k_analyze_prologue (pc, pc + m88k_max_prologue_size, NULL);
+}
+
+struct m88k_frame_cache *
+m88k_frame_cache (struct frame_info *next_frame, void **this_cache)
+{
+  struct m88k_frame_cache *cache;
+  CORE_ADDR frame_sp;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = FRAME_OBSTACK_ZALLOC (struct m88k_frame_cache);
+  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+  cache->fp_offset = -1;
+
+  cache->pc = frame_func_unwind (next_frame);
+  if (cache->pc != 0)
+    {
+      CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame);
+      m88k_analyze_prologue (cache->pc, addr_in_block, cache);
+    }
+
+  /* Calculate the stack pointer used in the prologue.  */
+  if (cache->fp_offset != -1)
+    {
+      CORE_ADDR fp;
+
+      fp = frame_unwind_register_unsigned (next_frame, M88K_R30_REGNUM);
+      frame_sp = fp - cache->fp_offset;
+    }
+  else
+    {
+      /* If we know where the return address is saved, we can take a
+         solid guess at what the frame pointer should be.  */
+      if (cache->saved_regs[M88K_R1_REGNUM].addr != -1)
+       cache->fp_offset = cache->saved_regs[M88K_R1_REGNUM].addr - 4;
+      frame_sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM);
+    }
+
+  /* Now that we know the stack pointer, adjust the location of the
+     saved registers.  */
+  {
+    int regnum;
+
+    for (regnum = M88K_R0_REGNUM; regnum < M88K_R31_REGNUM; regnum ++)
+      if (cache->saved_regs[regnum].addr != -1)
+       cache->saved_regs[regnum].addr += frame_sp;
+  }
+
+  /* Calculate the frame's base.  */
+  cache->base = frame_sp - cache->sp_offset;
+  trad_frame_set_value (cache->saved_regs, M88K_R31_REGNUM, cache->base);
+
+  /* Identify SXIP with the return address in R1.  */
+  cache->saved_regs[M88K_SXIP_REGNUM] = cache->saved_regs[M88K_R1_REGNUM];
+
+  *this_cache = cache;
+  return cache;
+}
+
+static void
+m88k_frame_this_id (struct frame_info *next_frame, void **this_cache,
+                   struct frame_id *this_id)
+{
+  struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return;
+
+  (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static void
+m88k_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+                         int regnum, int *optimizedp,
+                         enum lval_type *lvalp, CORE_ADDR *addrp,
+                         int *realnump, void *valuep)
+{
+  struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
+
+  if (regnum == M88K_SNIP_REGNUM || regnum == M88K_SFIP_REGNUM)
+    {
+      if (valuep)
+       {
+         CORE_ADDR pc;
+
+         trad_frame_get_prev_register (next_frame, cache->saved_regs,
+                                       M88K_SXIP_REGNUM, optimizedp,
+                                       lvalp, addrp, realnump, valuep);
+
+         pc = extract_unsigned_integer (valuep, 4);
+         if (regnum == M88K_SFIP_REGNUM)
+           pc += 4;
+         store_unsigned_integer (valuep, 4, pc + 4);
+       }
+
+      /* It's a computed value.  */
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      return;
+    }
+
+  trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
+                               optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind m88k_frame_unwind =
+{
+  NORMAL_FRAME,
+  m88k_frame_this_id,
+  m88k_frame_prev_register
+};
+
+static const struct frame_unwind *
+m88k_frame_sniffer (struct frame_info *next_frame)
+{
+  return &m88k_frame_unwind;
+}
+\f
+
+static CORE_ADDR
+m88k_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+  struct m88k_frame_cache *cache = m88k_frame_cache (next_frame, this_cache);
+
+  if (cache->fp_offset != -1)
+    return cache->base + cache->sp_offset + cache->fp_offset;
+
+  return 0;
+}
+
+static const struct frame_base m88k_frame_base =
+{
+  &m88k_frame_unwind,
+  m88k_frame_base_address,
+  m88k_frame_base_address,
+  m88k_frame_base_address
+};
+\f
+
+/* Core file support.  */
+
+/* Supply register REGNUM from the buffer specified by GREGS and LEN
+   in the general-purpose register set REGSET to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+
+static void
+m88k_supply_gregset (const struct regset *regset,
+                    struct regcache *regcache,
+                    int regnum, const void *gregs, size_t len)
+{
+  const char *regs = gregs;
+  int i;
+
+  for (i = 0; i < M88K_NUM_REGS; i++)
+    {
+      if (regnum == i || regnum == -1)
+       regcache_raw_supply (regcache, i, regs + i * 4);
+    }
+}
+
+/* Motorola 88000 register set.  */
+
+static struct regset m88k_gregset =
+{
+  NULL,
+  m88k_supply_gregset
+};
+
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+static const struct regset *
+m88k_regset_from_core_section (struct gdbarch *gdbarch,
+                              const char *sect_name, size_t sect_size)
+{
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= M88K_NUM_REGS * 4)
+    return &m88k_gregset;
+
+  return NULL;
+}
+\f
+
+static struct gdbarch *
+m88k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch *gdbarch;
+
+  /* If there is already a candidate, use it.  */
+  arches = gdbarch_list_lookup_by_info (arches, &info);
+  if (arches != NULL)
+    return arches->gdbarch;
+
+  /* Allocate space for the new architecture.  */
+  gdbarch = gdbarch_alloc (&info, NULL);
+
+  /* There is no real `long double'.  */
+  set_gdbarch_long_double_bit (gdbarch, 64);
+  set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);
+
+  set_gdbarch_num_regs (gdbarch, M88K_NUM_REGS);
+  set_gdbarch_register_name (gdbarch, m88k_register_name);
+  set_gdbarch_register_type (gdbarch, m88k_register_type);
+
+  /* Register numbers of various important registers.  */
+  set_gdbarch_sp_regnum (gdbarch, M88K_R31_REGNUM);
+  set_gdbarch_pc_regnum (gdbarch, M88K_SXIP_REGNUM);
+
+  /* Core file support.  */
+  set_gdbarch_regset_from_core_section
+    (gdbarch, m88k_regset_from_core_section);
+
+  set_gdbarch_print_insn (gdbarch, print_insn_m88k);
+
+  set_gdbarch_skip_prologue (gdbarch, m88k_skip_prologue);
+
+  /* Stack grows downward.  */
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+
+  /* Call dummy code.  */
+  set_gdbarch_push_dummy_call (gdbarch, m88k_push_dummy_call);
+  set_gdbarch_unwind_dummy_id (gdbarch, m88k_unwind_dummy_id);
+
+  /* Return value info */
+  set_gdbarch_return_value (gdbarch, m88k_return_value);
+
+  set_gdbarch_addr_bits_remove (gdbarch, m88k_addr_bits_remove);
+  set_gdbarch_breakpoint_from_pc (gdbarch, m88k_breakpoint_from_pc);
+  set_gdbarch_unwind_pc (gdbarch, m88k_unwind_pc);
+  set_gdbarch_write_pc (gdbarch, m88k_write_pc);
+
+  frame_base_set_default (gdbarch, &m88k_frame_base);
+  frame_unwind_append_sniffer (gdbarch, m88k_frame_sniffer);
+
+  return gdbarch;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_m88k_tdep (void);
+
+void
+_initialize_m88k_tdep (void)
+{
+  gdbarch_register (bfd_arch_m88k, m88k_gdbarch_init, NULL);
+}
diff --git a/gdb/m88k-tdep.h b/gdb/m88k-tdep.h
new file mode 100644 (file)
index 0000000..1389bfc
--- /dev/null
@@ -0,0 +1,49 @@
+/* Target-dependent code for the Motorola 88000 series.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 M88K_TDEP_H
+#define M88K_TDEP_H
+
+/* Register numbers of various important registers.  */
+
+enum m88k_regnum
+{
+  M88K_R0_REGNUM,
+  M88K_R1_REGNUM,              /* Return address (hardware).  */
+  M88K_R2_REGNUM,
+  M88K_R3_REGNUM,
+  M88K_R12_REGNUM = 12,
+  M88K_R30_REGNUM = 30,                /* Frame pointer.  */
+  M88K_R31_REGNUM,             /* Stack pointer. */
+  M88K_EPSR_REGNUM,
+  M88K_FPSR_REGNUM,
+  M88K_FPCR_REGNUM,
+  M88K_SXIP_REGNUM,
+  M88K_SNIP_REGNUM,
+  M88K_SFIP_REGNUM,
+  M88K_NUM_REGS                        /* Number of machine registers.  */
+
+};
+
+/* Instruction size.  */
+#define M88K_INSN_SIZE 4
+
+#endif /* m88k-tdep.h */
diff --git a/gdb/m88kbsd-nat.c b/gdb/m88kbsd-nat.c
new file mode 100644 (file)
index 0000000..7553c19
--- /dev/null
@@ -0,0 +1,94 @@
+/* Native-dependent code for Motorola 88000 BSD's.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "m88k-tdep.h"
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
+
+static void
+m88kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+  const char *regs = gregs;
+  int regnum;
+
+  for (regnum = 0; regnum < M88K_NUM_REGS; regnum++)
+    regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+   in GREGS.  */
+
+static void
+m88kbsd_collect_gregset (const struct regcache *regcache,
+                        void *gregs, int regnum)
+{
+  char *regs = gregs;
+  int i;
+
+  for (i = 0; i < M88K_NUM_REGS; i++)
+    {
+      if (regnum == -1 || regnum == i)
+       regcache_raw_collect (regcache, i, regs + i * 4);
+    }
+}
+\f
+
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers.  */
+
+void
+fetch_inferior_registers (int regnum)
+{
+  struct reg regs;
+
+  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't get registers");
+
+  m88kbsd_supply_gregset (current_regcache, &regs);
+}
+
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers.  */
+
+void
+store_inferior_registers (int regnum)
+{
+  struct reg regs;
+
+  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't get registers");
+
+  m88kbsd_collect_gregset (current_regcache, &regs, regnum);
+
+  if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't write registers");
+}
diff --git a/gdb/mi/gdb-mi.el b/gdb/mi/gdb-mi.el
new file mode 100644 (file)
index 0000000..8780e8a
--- /dev/null
@@ -0,0 +1,568 @@
+;;; gdb-mi.el (internally gdbmi6.el) - (24th May 2004)
+
+;; Run gdb with GDB/MI (-interp=mi) and access CLI using "cli-command"
+;; (could use "-interpreter-exec console cli-command")
+
+;; Author: Nick Roberts <nickrob@gnu.org>
+;; Maintainer: Nick Roberts <nickrob@gnu.org>
+;; Keywords: unix, tools
+
+;; Copyright (C) 2004  Free Software Foundation, Inc.
+
+;; This file is part of GNU GDB.
+
+;; GNU GDB 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, 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.
+
+;;; Commentary:
+
+;; This mode acts as a graphical user interface to GDB and requires GDB 6.1
+;; onwards. You can interact with GDB through the GUD buffer in the usual way,
+;; but there are also buffers which control the execution and describe the
+;; state of your program. It separates the input/output of your program from
+;; that of GDB and displays expressions and their current values in their own
+;; buffers. It also uses features of Emacs 21 such as the fringe/display
+;; margin for breakpoints, and the toolbar (see the GDB Graphical Interface
+;; section in the Emacs info manual).
+
+;; Start the debugger with M-x gdbmi.
+
+;; This file uses GDB/MI as the primary interface to GDB. It is still under
+;; development and is part of a process to migrate Emacs from annotations
+;; (as used in gdb-ui.el) to GDB/MI.
+
+;; Known Bugs:
+;;
+
+;;; Code:
+
+(require 'gud)
+(require 'gdb-ui)
+\f
+
+;;;###autoload
+(defun gdbmi (command-line)
+  "Run gdb on program FILE in buffer *gud-FILE*.
+The directory containing FILE becomes the initial working directory
+and source-file directory for your debugger.
+
+If `gdb-many-windows' is nil (the default value) then gdb just
+pops up the GUD buffer unless `gdb-show-main' is t. In this case
+it starts with two windows: one displaying the GUD buffer and the
+other with the source file with the main routine of the inferior.
+
+If `gdb-many-windows' is t, regardless of the value of
+`gdb-show-main', the layout below will appear. Keybindings are
+given in relevant buffer.
+
+Watch expressions appear in the speedbar/slowbar.
+
+The following interactive lisp functions help control operation :
+
+`gdb-many-windows'    - Toggle the number of windows gdb uses.
+`gdb-restore-windows' - To restore the window layout.
+
+See Info node `(emacs)GDB Graphical Interface' for a more
+detailed description of this mode.
+
+
+---------------------------------------------------------------------
+                               GDB Toolbar
+---------------------------------------------------------------------
+GUD buffer (I/O of GDB)           | Locals buffer
+                                  |
+                                  |
+                                  |
+---------------------------------------------------------------------
+ Source buffer                    | Input/Output (of inferior) buffer
+                                  | (comint-mode)
+                                  |
+                                  |
+                                  |
+                                  |
+                                  |
+                                  |
+---------------------------------------------------------------------
+ Stack buffer                     | Breakpoints buffer
+ RET      gdb-frames-select       | SPC    gdb-toggle-breakpoint
+                                  | RET    gdb-goto-breakpoint
+                                  |   d    gdb-delete-breakpoint
+---------------------------------------------------------------------
+"
+  ;;
+  (interactive (list (gud-query-cmdline 'gdbmi)))
+  ;;
+  ;; Let's start with a basic gud-gdb buffer and then modify it a bit.
+  (gdb command-line)
+  ;;
+  (setq gdb-debug-log nil)
+  (set (make-local-variable 'gud-minor-mode) 'gdbmi)
+  (set (make-local-variable 'gud-marker-filter) 'gud-gdbmi-marker-filter)
+  ;;
+  (gud-def gud-break (if (not (string-equal mode-name "Machine"))
+                        (gud-call "-break-insert %f:%l" arg)
+                      (save-excursion
+                        (beginning-of-line)
+                        (forward-char 2)
+                        (gud-call "-break-insert *%a" arg)))
+          "\C-b" "Set breakpoint at current line or address.")
+  ;;
+  (gud-def gud-remove (if (not (string-equal mode-name "Machine"))
+                         (gud-call "clear %f:%l" arg)
+                       (save-excursion
+                         (beginning-of-line)
+                         (forward-char 2)
+                         (gud-call "clear *%a" arg)))
+          "\C-d" "Remove breakpoint at current line or address.")
+  ;;
+  (gud-def gud-until  (if (not (string-equal mode-name "Machine"))
+                         (gud-call "until %f:%l" arg)
+                       (save-excursion
+                         (beginning-of-line)
+                         (forward-char 2)
+                         (gud-call "until *%a" arg)))
+          "\C-u" "Continue to current line or address.")
+
+  (define-key gud-minor-mode-map [left-margin mouse-1]
+    'gdb-mouse-toggle-breakpoint)
+  (define-key gud-minor-mode-map [left-fringe mouse-1]
+    'gdb-mouse-toggle-breakpoint)
+
+  (setq comint-input-sender 'gdbmi-send)
+  ;;
+  ;; (re-)initialise
+  (setq gdb-main-file nil)
+  (setq gdb-current-address "main")
+  (setq gdb-previous-address nil)
+  (setq gdb-previous-frame nil)
+  (setq gdb-current-frame "main")
+  (setq gdb-view-source t)
+  (setq gdb-selected-view 'source)
+  (setq gdb-var-list nil)
+  (setq gdb-var-changed nil)
+  (setq gdb-prompting nil)
+  (setq gdb-current-item nil)
+  (setq gdb-pending-triggers nil)
+  (setq gdb-output-sink 'user)
+  (setq gdb-server-prefix nil)
+  ;;
+  (setq gdb-buffer-type 'gdbmi)
+  ;;
+  ;; FIXME: use tty command to separate io.
+  ;;(gdb-clear-inferior-io)
+  ;;
+  (if (eq window-system 'w32)
+      (gdb-enqueue-input (list "-gdb-set new-console off\n" 'ignore)))
+  ;; find source file and compilation directory here
+  (gdb-enqueue-input (list "list main\n"   'ignore))   ; C program
+  (gdb-enqueue-input (list "list MAIN__\n" 'ignore))   ; Fortran program
+  (gdb-enqueue-input (list "info source\n" 'gdbmi-source-info))
+  ;;
+  (run-hooks 'gdbmi-mode-hook))
+
+; Force nil till fixed.
+(defconst gdbmi-use-inferior-io-buffer nil)
+
+; uses --all-values Needs GDB 6.1 onwards.
+(defun gdbmi-var-list-children (varnum)
+  (gdb-enqueue-input
+   (list (concat "-var-update " varnum "\n") 'ignore))
+  (gdb-enqueue-input
+   (list (concat "-var-list-children --all-values "  
+                varnum "\n")
+            `(lambda () (gdbmi-var-list-children-handler ,varnum)))))
+
+(defconst gdbmi-var-list-children-regexp
+"name=\"\\(.*?\\)\",exp=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",value=\"\\(.*?\\)\""
+)
+
+(defun gdbmi-var-list-children-handler (varnum)
+  (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+    (goto-char (point-min))
+    (let ((var-list nil))
+     (catch 'child-already-watched
+       (dolist (var gdb-var-list)
+        (if (string-equal varnum (cadr var))
+            (progn
+              (push var var-list)
+              (while (re-search-forward gdbmi-var-list-children-regexp nil t)
+                (let ((varchild (list (match-string 2)
+                                      (match-string 1)
+                                      (match-string 3)
+                                      nil
+                                      (match-string 4)
+                                      nil)))
+                  (if (looking-at ",type=\"\\(.*?\\)\"")
+                      (setcar (nthcdr 3 varchild) (match-string 1)))
+                  (dolist (var1 gdb-var-list)
+                    (if (string-equal (cadr var1) (cadr varchild))
+                        (throw 'child-already-watched nil)))
+                  (push varchild var-list))))
+          (push var var-list)))
+       (setq gdb-var-changed t)
+       (setq gdb-var-list (nreverse var-list))))))
+\f
+;(defun gdbmi-send (proc string)
+;  "A comint send filter for gdb."
+;  (setq gdb-output-sink 'user)
+;  (setq gdb-prompting nil)
+;  (process-send-string proc (concat "-interpreter-exec console \"" string "\"")))
+
+(defun gdbmi-send (proc string)
+  "A comint send filter for gdb."
+  (setq gdb-output-sink 'user)
+  (setq gdb-prompting nil)
+  (process-send-string proc (concat string "\n")))
+
+(defcustom gud-gdbmi-command-name "~/gdb/gdb/gdb -interp=mi"
+  "Default command to execute an executable under the GDB-UI debugger."
+  :type 'string
+  :group 'gud)
+
+(defconst gdb-stopped-regexp 
+  "\\((gdb) \n\\*stopped\\|^\\^done\\),reason=.*,file=\"\\(.*\\)\",line=\"\\(.*\\)\".*")
+
+(defconst gdb-console-regexp "~\"\\(.*\\)\\\\n\"")
+
+(defconst gdb-internals-regexp "&\".*\\n\"\n")
+
+(defconst gdb-gdb-regexp "(gdb) \n")
+
+(defconst gdb-running-regexp "^\\^running")
+
+(defun gdbmi-prompt ()
+  "This handler terminates the any collection of output. It also
+  sends the next command (if any) to gdb."
+  (unless gdb-pending-triggers
+       (gdb-get-current-frame)
+       (gdbmi-invalidate-frames)
+       (gdbmi-invalidate-breakpoints)
+       (gdbmi-invalidate-locals)
+       (dolist (frame (frame-list))
+         (when (string-equal (frame-parameter frame 'name) "Speedbar")
+           (setq gdb-var-changed t)    ; force update
+           (dolist (var gdb-var-list)
+             (setcar (nthcdr 5 var) nil))))
+       (gdb-var-update))
+  (let ((sink gdb-output-sink))
+    (when (eq sink 'emacs)
+      (let ((handler
+            (car (cdr gdb-current-item))))
+       (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+         (funcall handler)))))
+  (let ((input (gdb-dequeue-input)))
+    (if input
+       (gdb-send-item input)
+      (progn
+       (setq gud-running nil)
+       (setq gdb-prompting t)
+       (gud-display-frame)))))
+
+(defun gud-gdbmi-marker-filter (string)
+  "Filter GDB/MI output."
+  (if gdb-enable-debug-log (push (cons 'recv string) gdb-debug-log))
+  ;; Recall the left over gud-marker-acc from last time
+  (setq gud-marker-acc (concat gud-marker-acc string))
+  ;; Start accumulating output for the GUD buffer
+  (let ((output ""))
+
+    (if (string-match gdb-running-regexp gud-marker-acc) 
+       (setq gud-marker-acc (substring gud-marker-acc (match-end 0))
+            gud-running t))
+
+    ;; Remove the trimmings from the console stream.
+    (while (string-match gdb-console-regexp gud-marker-acc) 
+       (setq 
+       gud-marker-acc (concat (substring gud-marker-acc 0 (match-beginning 0))
+                              (match-string 1 gud-marker-acc)
+                              (substring gud-marker-acc (match-end 0)))))
+
+    ;; Remove log stream containing debugging messages being produced by GDB's
+    ;; internals.
+    (while (string-match gdb-internals-regexp gud-marker-acc) 
+       (setq 
+        gud-marker-acc (concat (substring gud-marker-acc 0 (match-beginning 0))
+                               (substring gud-marker-acc (match-end 0)))))
+
+    (if (string-match gdb-stopped-regexp gud-marker-acc)
+      (setq
+
+       ;; Extract the frame position from the marker.
+       gud-last-frame (cons (match-string 2 gud-marker-acc)
+                           (string-to-int (match-string 3 gud-marker-acc)))
+
+       ;; Append any text before the marker to the output we're going
+       ;; to return - we don't include the marker in this text.
+       output (gdbmi-concat-output output
+                     (substring gud-marker-acc 0 (match-beginning 0)))
+
+       ;; Set the accumulator to the remaining text.
+       gud-marker-acc (substring gud-marker-acc (match-end 0))))
+      
+    (while (string-match gdb-gdb-regexp gud-marker-acc) 
+      (setq
+
+       ;; Append any text up to and including prompt less \n to the output.
+       output (gdbmi-concat-output output
+                     (substring gud-marker-acc 0 (- (match-end 0) 1)))
+
+       ;; Set the accumulator to the remaining text.
+       gud-marker-acc (substring gud-marker-acc (match-end 0)))
+      (gdbmi-prompt))
+
+    (setq output (gdbmi-concat-output output gud-marker-acc))
+    (setq gud-marker-acc "")
+    output))
+
+(defun gdbmi-concat-output (so-far new)
+  (let ((sink gdb-output-sink))
+    (cond
+     ((eq sink 'user) (concat so-far new))
+     ((eq sink 'emacs)
+      (gdb-append-to-partial-output new)
+      so-far)
+     ((eq sink 'inferior)
+      (gdb-append-to-inferior-io new)
+      so-far))))
+\f
+
+;; Breakpoint buffer : This displays the output of `-break-list'.
+;;
+(def-gdb-auto-updated-buffer gdb-breakpoints-buffer
+  ;; This defines the auto update rule for buffers of type
+  ;; `gdb-breakpoints-buffer'.
+  ;;
+  ;; It defines a function that queues the command below.  That function is
+  ;; called:
+  gdbmi-invalidate-breakpoints
+  ;;
+  ;; To update the buffer, this command is sent to gdb.
+  "-break-list\n"
+  ;;
+  ;; This also defines a function to be the handler for the output
+  ;; from the command above.  That function will copy the output into
+  ;; the appropriately typed buffer.  That function will be called:
+  gdb-break-list-handler
+  ;; buffer specific functions
+  gdb-break-list-custom)
+
+(defconst gdb-break-list-regexp
+"number=\"\\(.*?\\)\",type=\"\\(.*?\\)\",disp=\"\\(.*?\\)\",enabled=\"\\(.\\)\",addr=\"\\(.*?\\)\",func=\"\\(.*?\\)\",file=\"\\(.*?\\)\",line=\"\\(.*?\\)\"")
+
+(defun gdb-break-list-handler ()
+  (setq gdb-pending-triggers (delq 'gdbmi-invalidate-breakpoints
+                                 gdb-pending-triggers))
+  (let ((breakpoint nil)
+       (breakpoints-list nil))
+    (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+      (goto-char (point-min))
+      (while (re-search-forward gdb-break-list-regexp nil t)
+       (let ((breakpoint (list (match-string 1)
+                               (match-string 2)
+                               (match-string 3)
+                               (match-string 4)
+                               (match-string 5)
+                               (match-string 6)
+                               (match-string 7)
+                               (match-string 8))))
+         (push breakpoint breakpoints-list))))
+    (let ((buf (gdb-get-buffer 'gdb-breakpoints-buffer)))
+      (and buf (with-current-buffer buf
+                (let ((p (point))
+                      (buffer-read-only nil))
+                  (erase-buffer)
+                  (insert "Num Type        Disp Enb Func\tFile:Line\tAddr\n")
+                  (dolist (breakpoint breakpoints-list)
+                    (insert (concat
+                             (nth 0 breakpoint) "   "
+                             (nth 1 breakpoint) "  "
+                             (nth 2 breakpoint) "   "
+                             (nth 3 breakpoint) " "
+                             (nth 5 breakpoint) "\t"
+                             (nth 6 breakpoint) ":" (nth 7 breakpoint) "\t" 
+                             (nth 4 breakpoint) "\n")))
+                  (goto-char p))))))
+  (gdb-break-list-custom))
+
+;;-put breakpoint icons in relevant margins (even those set in the GUD buffer)
+(defun gdb-break-list-custom ()
+  (let ((flag)(address))
+    ;;
+    ;; remove all breakpoint-icons in source buffers but not assembler buffer
+    (dolist (buffer (buffer-list))
+      (with-current-buffer buffer
+       (if (and (eq gud-minor-mode 'gdbmi)
+                (not (string-match "\\`\\*.+\\*\\'" (buffer-name))))
+           (gdb-remove-breakpoint-icons (point-min) (point-max)))))
+    (with-current-buffer (gdb-get-buffer 'gdb-breakpoints-buffer)
+      (save-excursion
+       (goto-char (point-min))
+       (while (< (point) (- (point-max) 1))
+         (forward-line 1)
+         (if (looking-at "[0-9]*\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)\\s-*\\S-*\\s-*\\(\\S-*\\):\\([0-9]+\\)")
+             (progn
+               (setq flag (char-after (match-beginning 1)))
+               (let ((line (match-string 3)) (buffer-read-only nil)
+                     (file (match-string 2)))
+                 (add-text-properties (point-at-bol) (point-at-eol)
+                                      '(mouse-face highlight
+                                                   help-echo "mouse-2, RET: visit breakpoint"))
+                 (with-current-buffer
+                     (find-file-noselect
+                      (if (file-exists-p file) file
+                        (expand-file-name file gdb-cdir)))
+                   (save-current-buffer
+                     (set (make-local-variable 'gud-minor-mode) 'gdbmi)
+                     (set (make-local-variable 'tool-bar-map)
+                          gud-tool-bar-map))
+                   ;; only want one breakpoint icon at each location
+                   (save-excursion
+                     (goto-line (string-to-number line))
+                     (gdb-put-breakpoint-icon (eq flag ?y)))))))))
+         (end-of-line)))
+  (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom)))
+
+;; Frames buffer.  This displays a perpetually correct bactrack trace.
+;;
+(def-gdb-auto-updated-buffer gdb-stack-buffer
+  gdbmi-invalidate-frames
+  "-stack-list-frames\n"
+  gdb-stack-list-frames-handler
+  gdb-stack-list-frames-custom)
+
+(defconst gdb-stack-list-frames-regexp
+"level=\"\\(.*?\\)\",addr=\"\\(.*?\\)\",func=\"\\(.*?\\)\",file=\"\\(.*?\\)\",line=\"\\(.*?\\)\"")
+
+(defun gdb-stack-list-frames-handler ()
+  (setq gdb-pending-triggers (delq 'gdbmi-invalidate-frames
+                                 gdb-pending-triggers))
+  (let ((frame nil)
+       (call-stack nil))
+    (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+      (goto-char (point-min))
+      (while (re-search-forward gdb-stack-list-frames-regexp nil t)
+       (let ((frame (list (match-string 1)
+                          (match-string 2)
+                          (match-string 3)
+                          (match-string 4)
+                          (match-string 5))))
+         (push frame call-stack))))
+    (let ((buf (gdb-get-buffer 'gdb-stack-buffer)))
+      (and buf (with-current-buffer buf
+                (let ((p (point))
+                      (buffer-read-only nil))
+                  (erase-buffer)
+                  (insert "Level\tFunc\tFile:Line\tAddr\n")
+                  (dolist (frame (nreverse call-stack))
+                    (insert (concat
+                             (nth 0 frame) "\t"
+                             (nth 2 frame) "\t"
+                             (nth 3 frame) ":" (nth 4 frame) "\t"
+                             (nth 1 frame) "\n")))
+                  (goto-char p))))))
+  (gdb-stack-list-frames-custom))
+
+(defun gdb-stack-list-frames-custom ()
+  (with-current-buffer (gdb-get-buffer 'gdb-stack-buffer)
+    (save-excursion
+      (let ((buffer-read-only nil))
+       (goto-char (point-min))
+       (forward-line 1)
+       (while (< (point) (point-max))
+         (add-text-properties (point-at-bol) (point-at-eol)
+                            '(mouse-face highlight
+                              help-echo "mouse-2, RET: Select frame"))
+         (beginning-of-line)
+         (when (and (or (looking-at "^#[0-9]*\\s-*\\S-* in \\(\\S-*\\)")
+                        (looking-at "^#[0-9]*\\s-*\\(\\S-*\\)"))
+                    (equal (match-string 1) gdb-current-frame))
+           (put-text-property (point-at-bol) (point-at-eol)
+                              'face '(:inverse-video t)))
+         (forward-line 1))))))
+
+;; Locals buffer.
+;; uses "-stack-list-locals 2". Needs GDB 6.1 onwards.
+(def-gdb-auto-updated-buffer gdb-locals-buffer
+  gdbmi-invalidate-locals
+  "-stack-list-locals 2\n"
+  gdb-stack-list-locals-handler
+  gdb-stack-list-locals-custom)
+
+(defconst gdb-stack-list-locals-regexp
+  (concat "name=\"\\(.*?\\)\",type=\"\\(.*?\\)\""))
+
+;; Dont display values of arrays or structures.
+;; These can be expanded using gud-watch.
+(defun gdb-stack-list-locals-handler nil
+  (setq gdb-pending-triggers (delq 'gdbmi-invalidate-locals
+                                 gdb-pending-triggers))
+  (let ((local nil)
+       (locals-list nil))
+    (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer)
+      (goto-char (point-min))
+      (while (re-search-forward gdb-stack-list-locals-regexp nil t)
+       (let ((local (list (match-string 1)
+                          (match-string 2)
+                          nil)))
+         (if (looking-at ",value=\"\\(.*?\\)\"")
+             (setcar (nthcdr 2 local) (match-string 1)))
+       (push local locals-list))))
+    (let ((buf (gdb-get-buffer 'gdb-locals-buffer)))
+      (and buf (with-current-buffer buf
+                (let ((p (point))
+                      (buffer-read-only nil))
+                  (erase-buffer)
+                  (dolist (local locals-list)
+                    (insert 
+                     (concat (car local) "\t" (nth 1 local) "\t"
+                             (or (nth 2 local)
+                                 (if (string-match "struct" (nth 1 local))
+                                     "(structure)"
+                                   "(array)"))
+                             "\n")))
+                  (goto-char p)))))))
+
+(defun gdb-stack-list-locals-custom ()
+  nil)
+
+(defun gdbmi-source-info ()
+  "Find the source file where the program starts and displays it with related
+buffers."
+  (goto-char (point-min))
+  (if (search-forward "source file is " nil t)
+      (if (looking-at "\\S-*")
+         (setq gdb-main-file (match-string 0)))
+    (setq gdb-view-source nil))
+  (if (search-forward "directory is " nil t)
+      (if (looking-at "\\S-*:\\(\\S-*\\)")
+         (setq gdb-cdir (match-string 1))
+       (looking-at "\\S-*")
+       (setq gdb-cdir (match-string 0))))
+
+;temporary heuristic
+  (if gdb-main-file
+      (setq gdb-main-file (expand-file-name gdb-main-file gdb-cdir)))
+
+  (if gdb-many-windows
+      (gdb-setup-windows)
+    (gdb-get-create-buffer 'gdb-breakpoints-buffer)
+    (when gdb-show-main
+      (switch-to-buffer gud-comint-buffer)
+      (delete-other-windows)
+      (split-window)
+      (other-window 1)
+      (switch-to-buffer
+       (if gdb-view-source
+          (gud-find-file gdb-main-file)
+        (gdb-get-create-buffer 'gdb-assembler-buffer)))
+      (other-window 1))))
+
+(provide 'gdb-mi)
+;;; gdbmi.el ends here
diff --git a/gdb/observer.sh b/gdb/observer.sh
new file mode 100755 (executable)
index 0000000..b23f15e
--- /dev/null
@@ -0,0 +1,157 @@
+#!/bin/sh -e
+
+if test $# -ne 3
+then
+    echo "Usage: $0 <h|inc> <observer.texi> <observer.out>" 1>&2
+    exit 0
+fi
+
+lang=$1 ; shift
+texi=$1 ; shift
+o=$1 ; shift
+echo "Creating ${o}-tmp" 1>&2
+rm -f ${o}-tmp
+
+# Can use any of the following: cat cmp cp diff echo egrep expr false
+# grep install-info ln ls mkdir mv pwd rm rmdir sed sleep sort tar
+# test touch true
+
+cat <<EOF >>${o}-tmp
+/* GDB Notifications to Observers.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.
+
+   --
+
+   This file was generated using observer.sh and observer.texi.  */
+
+EOF
+
+
+case $lang in
+    h) cat <<EOF >>${o}-tmp
+#ifndef OBSERVER_H
+#define OBSERVER_H
+
+struct observer;
+struct bpstats;
+struct so_list;
+EOF
+        ;;
+esac
+
+
+# generate a list of events that can be observed
+
+IFS=:
+sed -n '
+/@deftypefun void/{
+# Save original line for later processing into the actual parameter
+    h
+# Convert from: @deftypefun void EVENT (TYPE @var{PARAM},...)
+# to event and formals: EVENT:TYPE PARAM, ...:
+    s/^.* void \([a-z_][a-z_]*\) (\(.*\))$/\1:\2/
+    s/@var{//g
+    s/}//g
+# Switch to held
+    x
+# Convert from: @deftypefun void FUNC (TYPE @var{PARAM},...)
+# to actuals: PARAM, ...
+    s/^[^{]*[{]*//
+    s/[}]*[^}]*$//
+    s/}[^{]*{/, /g
+# Combine held (EVENT:TYPE PARAM, ...:) and pattern (PARAM, ...) into
+# FUNC:TYPE PARAM, ...:PARAM, ...
+    H
+    x
+    s/\n/:/g
+    p
+}
+' $texi | while read event formal actual
+do
+  case $lang in
+      h) cat <<EOF >>${o}-tmp
+
+/* ${event} notifications.  */
+
+typedef void (observer_${event}_ftype) (${formal});
+
+extern struct observer *observer_attach_${event} (observer_${event}_ftype *f);
+extern void observer_detach_${event} (struct observer *observer);
+extern void observer_notify_${event} (${formal});
+EOF
+       ;;
+
+      inc)
+       cat <<EOF >>${o}-tmp
+
+/* ${event} notifications.  */
+
+static struct observer_list *${event}_subject = NULL;
+
+struct ${event}_args { `echo "${formal}" | sed -e 's/,/;/g'`; };
+
+static void
+observer_${event}_notification_stub (const void *data, const void *args_data)
+{
+  observer_${event}_ftype *notify = (observer_${event}_ftype *) data;
+  const struct ${event}_args *args = args_data;
+  notify (`echo ${actual} | sed -e 's/\([a-z0-9_][a-z0-9_]*\)/args->\1/g'`);
+}
+
+struct observer *
+observer_attach_${event} (observer_${event}_ftype *f)
+{
+  return generic_observer_attach (&${event}_subject,
+                                 &observer_${event}_notification_stub,
+                                 (void *) f);
+}
+
+void
+observer_detach_${event} (struct observer *observer)
+{
+  generic_observer_detach (&${event}_subject, observer);
+}
+
+void
+observer_notify_${event} (${formal})
+{
+  struct ${event}_args args;
+  `echo ${actual} | sed -e 's/\([a-z0-9_][a-z0-9_]*\)/args.\1 = \1/g'`;
+  if (observer_debug)
+    fprintf_unfiltered (gdb_stdlog, "observer_notify_${event}() called\n");
+  generic_observer_notify (${event}_subject, &args);
+}
+EOF
+       ;;
+    esac
+done
+
+
+case $lang in
+    h) cat <<EOF >>${o}-tmp
+
+#endif /* OBSERVER_H */
+EOF
+esac
+
+
+echo Moving ${o}-tmp to ${o}
+mv ${o}-tmp ${o}
diff --git a/gdb/po/gdbtext b/gdb/po/gdbtext
new file mode 100755 (executable)
index 0000000..1f80cf9
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh -e
+
+if test $# -lt 3
+then
+    echo "Usage: $0 <xgettext> <package>  <directory> ..." 1>&2
+    exit 0
+fi
+
+xgettext=$1 ; shift
+package=$1 ; shift
+
+for d in "$@"
+do
+  __directories="$__directories --directory=$d"
+done
+
+for d in "$@"
+do
+  (
+      cd $d
+      find * \
+         -name '*-stub.c' -prune -o \
+         -name 'testsuite' -prune -o \
+         -name 'init.c' -prune -o \
+         -name '*.[hc]' -print
+  )
+done | ${xgettext} \
+    --default-domain=${package} \
+    --copyright-holder="Free Software Foundation, Inc." \
+    --add-comments \
+    --files-from=- \
+    --force-po \
+    --debug \
+    --language=c \
+    --keyword=_ \
+    --keyword=N_ \
+    ${__directories} \
+    -o po/${package}.pot
diff --git a/gdb/ppcobsd-nat.c b/gdb/ppcobsd-nat.c
new file mode 100644 (file)
index 0000000..c36c63f
--- /dev/null
@@ -0,0 +1,98 @@
+/* Native-dependent code for OpenBSD/powerpc.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "ppc-tdep.h"
+#include "ppcobsd-tdep.h"
+
+/* OpenBSD/powerpc doesn't have PT_GETFPREGS/PT_SETFPREGS like
+   NetBSD/powerpc and FreeBSD/powerpc.  */
+
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers.  */
+
+void
+fetch_inferior_registers (int regnum)
+{
+  struct reg regs;
+
+  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't get registers");
+
+  ppcobsd_supply_gregset (&ppcobsd_gregset, current_regcache, -1,
+                         &regs, sizeof regs);
+}
+
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers.  */
+
+void
+store_inferior_registers (int regnum)
+{
+  struct reg regs;
+
+  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't get registers");
+
+  ppcobsd_collect_gregset (&ppcobsd_gregset, current_regcache,
+                          regnum, &regs, sizeof regs);
+
+  if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't write registers");
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_ppcobsd_nat (void);
+
+void
+_initialize_ppcobsd_nat (void)
+{
+  /* General-purpose registers.  */
+  ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
+  ppcobsd_reg_offsets.pc_offset = offsetof (struct reg, pc);
+  ppcobsd_reg_offsets.ps_offset = offsetof (struct reg, ps);
+  ppcobsd_reg_offsets.cr_offset = offsetof (struct reg, cnd);
+  ppcobsd_reg_offsets.lr_offset = offsetof (struct reg, lr);
+  ppcobsd_reg_offsets.ctr_offset = offsetof (struct reg, cnt);
+  ppcobsd_reg_offsets.xer_offset = offsetof (struct reg, xer);
+  ppcobsd_reg_offsets.mq_offset = offsetof (struct reg, mq);
+
+  /* Floating-point registers.  */
+  ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr);
+  ppcobsd_reg_offsets.fpscr_offset = -1;
+
+  /* AltiVec registers.  */
+  ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
+  ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
+  ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);
+}
diff --git a/gdb/ppcobsd-tdep.c b/gdb/ppcobsd-tdep.c
new file mode 100644 (file)
index 0000000..49a8601
--- /dev/null
@@ -0,0 +1,178 @@
+/* Target-dependent code for OpenBSD/powerpc.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "gdb_assert.h"
+
+#include "gdb_string.h"
+
+#include "ppc-tdep.h"
+#include "ppcobsd-tdep.h"
+#include "solib-svr4.h"
+
+/* Register offsets from <machine/reg.h>.  */
+struct ppc_reg_offsets ppcobsd_reg_offsets;
+\f
+
+/* Core file support.  */
+
+/* Supply register REGNUM in the general-purpose register set REGSET
+   from the buffer specified by GREGS and LEN to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+
+void
+ppcobsd_supply_gregset (const struct regset *regset,
+                       struct regcache *regcache, int regnum,
+                       const void *gregs, size_t len)
+{
+  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+     point registers.  Traditionally, GDB's register set has still
+     listed the floating point registers for such machines, so this
+     code is harmless.  However, the new E500 port actually omits the
+     floating point registers entirely from the register set --- they
+     don't even have register numbers assigned to them.
+
+     It's not clear to me how best to update this code, so this assert
+     will alert the first person to encounter the OpenBSD/E500
+     combination to the problem.  */
+  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
+
+  ppc_supply_gregset (regset, regcache, regnum, gregs, len);
+  ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* Collect register REGNUM in the general-purpose register set
+   REGSET. from register cache REGCACHE into the buffer specified by
+   GREGS and LEN.  If REGNUM is -1, do this for all registers in
+   REGSET.  */
+
+void
+ppcobsd_collect_gregset (const struct regset *regset,
+                        const struct regcache *regcache, int regnum,
+                        void *gregs, size_t len)
+{
+  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
+     point registers.  Traditionally, GDB's register set has still
+     listed the floating point registers for such machines, so this
+     code is harmless.  However, the new E500 port actually omits the
+     floating point registers entirely from the register set --- they
+     don't even have register numbers assigned to them.
+
+     It's not clear to me how best to update this code, so this assert
+     will alert the first person to encounter the OpenBSD/E500
+     combination to the problem.  */
+  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
+
+  ppc_collect_gregset (regset, regcache, regnum, gregs, len);
+  ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* OpenBS/powerpc register set.  */
+
+struct regset ppcobsd_gregset =
+{
+  &ppcobsd_reg_offsets,
+  ppcobsd_supply_gregset
+};
+
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+static const struct regset *
+ppcobsd_regset_from_core_section (struct gdbarch *gdbarch,
+                                 const char *sect_name, size_t sect_size)
+{
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= 412)
+    return &ppcobsd_gregset;
+
+  return NULL;
+}
+\f
+
+static void
+ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  /* OpenBSD uses SVR4-style shared libraries.  */
+  set_gdbarch_in_solib_call_trampoline
+    (gdbarch, generic_in_solib_call_trampoline);
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  set_gdbarch_regset_from_core_section
+    (gdbarch, ppcobsd_regset_from_core_section);
+}
+\f
+
+/* OpenBSD uses uses the traditional NetBSD core file format, even for
+   ports that use ELF.  */
+#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF
+
+static enum gdb_osabi
+ppcobsd_core_osabi_sniffer (bfd *abfd)
+{
+  if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+    return GDB_OSABI_NETBSD_CORE;
+
+  return GDB_OSABI_UNKNOWN;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_ppcobsd_tdep (void);
+
+void
+_initialize_ppcobsd_tdep (void)
+{
+  /* BFD doesn't set a flavour for NetBSD style a.out core files.  */
+  gdbarch_register_osabi_sniffer (bfd_arch_powerpc, bfd_target_unknown_flavour,
+                                  ppcobsd_core_osabi_sniffer);
+
+  gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD_ELF,
+                         ppcobsd_init_abi);
+
+  /* Avoid initializing the register offsets again if they were
+     already initailized by ppcobsd-nat.c.  */
+  if (ppcobsd_reg_offsets.pc_offset == 0)
+    {
+      /* General-purpose registers.  */
+      ppcobsd_reg_offsets.r0_offset = 0;
+      ppcobsd_reg_offsets.pc_offset = 384;
+      ppcobsd_reg_offsets.ps_offset = 388;
+      ppcobsd_reg_offsets.cr_offset = 392;
+      ppcobsd_reg_offsets.lr_offset = 396;
+      ppcobsd_reg_offsets.ctr_offset = 400;
+      ppcobsd_reg_offsets.xer_offset = 404;
+      ppcobsd_reg_offsets.mq_offset = 408;
+
+      /* Floating-point registers.  */
+      ppcobsd_reg_offsets.f0_offset = 128;
+      ppcobsd_reg_offsets.fpscr_offset = -1;
+
+      /* AltiVec registers.  */
+      ppcobsd_reg_offsets.vr0_offset = 0;
+      ppcobsd_reg_offsets.vscr_offset = 512;
+      ppcobsd_reg_offsets.vrsave_offset = 520;
+    }
+}
diff --git a/gdb/ppcobsd-tdep.h b/gdb/ppcobsd-tdep.h
new file mode 100644 (file)
index 0000000..8f29aaa
--- /dev/null
@@ -0,0 +1,54 @@
+/* Target-dependent code for OpenBSD/powerpc.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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 PPCOBSD_TDEP_H
+#define PPCOBSD_TDEP_H
+
+#include <stddef.h>
+
+struct regset;
+struct regcache;
+
+/* Register offsets for OpenBSD/powerpc.  */
+extern struct ppc_reg_offsets ppcobsd_reg_offsets;
+
+/* Register sets for OpenBSD/powerpc.  */
+extern struct regset ppcobsd_gregset;
+\f
+
+/* Supply register REGNUM in the general-purpose register set REGSET
+   from the buffer specified by GREGS and LEN to register cache
+   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
+
+extern void ppcobsd_supply_gregset (const struct regset *regset,
+                                   struct regcache *regcache, int regnum,
+                                   const void *gregs, size_t len);
+
+/* Collect register REGNUM in the general-purpose register set
+   REGSET. from register cache REGCACHE into the buffer specified by
+   GREGS and LEN.  If REGNUM is -1, do this for all registers in
+   REGSET.  */
+
+extern void ppcobsd_collect_gregset (const struct regset *regset,
+                                    const struct regcache *regcache,
+                                    int regnum, void *gregs, size_t len);
+
+#endif /* ppcobsd-tdep.h */
diff --git a/gdb/regset.c b/gdb/regset.c
new file mode 100644 (file)
index 0000000..d588b7d
--- /dev/null
@@ -0,0 +1,46 @@
+/* Manage register sets.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "regset.h"
+
+#include "gdb_assert.h"
+
+/* Allocate a fresh 'struct regset' whose supply_regset function is
+   SUPPLY_REGSET, and whose collect_regset function is COLLECT_REGSET.
+   If the regset has no collect_regset function, pass NULL for
+   COLLECT_REGSET.
+
+   The object returned is allocated on ARCH's obstack.  */
+
+struct regset *
+regset_alloc (struct gdbarch *arch,
+              supply_regset_ftype *supply_regset,
+              collect_regset_ftype *collect_regset)
+{
+  struct regset *regset = GDBARCH_OBSTACK_ZALLOC (arch, struct regset);
+
+  regset->arch = arch;
+  regset->supply_regset = supply_regset;
+  regset->collect_regset = collect_regset;
+
+  return regset;
+}
diff --git a/gdb/symfile-mem.c b/gdb/symfile-mem.c
new file mode 100644 (file)
index 0000000..71991cf
--- /dev/null
@@ -0,0 +1,146 @@
+/* Reading symbol files from memory.
+
+   Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000,
+   2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+/* This file defines functions (and commands to exercise those
+   functions) for reading debugging information from object files
+   whose images are mapped directly into the inferior's memory.  For
+   example, the Linux kernel maps a "syscall DSO" into each process's
+   address space; this DSO provides kernel-specific code for some
+   system calls.
+
+   At the moment, BFD only has functions for parsing object files from
+   memory for the ELF format, even though the general idea isn't
+   ELF-specific.  This means that BFD only provides the functions GDB
+   needs when configured for ELF-based targets.  So these functions
+   may only be compiled on ELF-based targets.
+
+   GDB has no idea whether it has been configured for an ELF-based
+   target or not: it just tries to handle whatever files it is given.
+   But this means there are no preprocessor symbols on which we could
+   make these functions' compilation conditional.
+
+   So, for the time being, we put these functions alone in this file,
+   and have .mt files reference them as appropriate.  In the future, I
+   hope BFD will provide a format-independent bfd_from_remote_memory
+   entry point.  */
+
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbcore.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "value.h"
+#include "symfile.h"
+
+
+/* Read inferior memory at ADDR to find the header of a loaded object file
+   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
+   representing the target's format.  */
+static struct objfile *
+symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, int from_tty)
+{
+  struct objfile *objf;
+  struct bfd *nbfd;
+  struct bfd_section *sec;
+  bfd_vma loadbase;
+  struct section_addr_info *sai;
+  unsigned int i;
+
+  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
+    error ("add-symbol-file-from-memory not supported for this target");
+
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+                                        target_read_memory);
+  if (nbfd == NULL)
+    error ("Failed to read a valid object file image from memory.");
+
+  nbfd->filename = xstrdup ("shared object read from target memory");
+
+  if (!bfd_check_format (nbfd, bfd_object))
+    {
+      /* FIXME: should be checking for errors from bfd_close (for one thing,
+         on error it does not free all the storage associated with the
+         bfd).  */
+      bfd_close (nbfd);
+      error ("Got object file from memory but can't read symbols: %s.",
+            bfd_errmsg (bfd_get_error ()));
+    }
+
+  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
+  make_cleanup (xfree, sai);
+  i = 0;
+  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
+    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
+      {
+       sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
+       sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
+       sai->other[i].sectindex = sec->index;
+       ++i;
+      }
+
+  objf = symbol_file_add_from_bfd (nbfd, from_tty,
+                                   sai, 0, OBJF_SHARED);
+
+  /* This might change our ideas about frames already looked at.  */
+  reinit_frame_cache ();
+
+  return objf;
+}
+
+
+static void
+add_symbol_file_from_memory_command (char *args, int from_tty)
+{
+  CORE_ADDR addr;
+  struct bfd *templ;
+
+  if (args == NULL)
+    error ("add-symbol-file-from-memory requires an expression argument");
+
+  addr = parse_and_eval_address (args);
+
+  /* We need some representative bfd to know the target we are looking at.  */
+  if (symfile_objfile != NULL)
+    templ = symfile_objfile->obfd;
+  else
+    templ = exec_bfd;
+  if (templ == NULL)
+    error ("\
+Must use symbol-file or exec-file before add-symbol-file-from-memory.");
+
+  symbol_file_add_from_memory (templ, addr, from_tty);
+}
+
+\f
+void
+_initialize_symfile_mem (void)
+{
+  add_cmd ("add-symbol-file-from-memory", class_files,
+           add_symbol_file_from_memory_command,
+           "\
+Load the symbols out of memory from a dynamically loaded object file.\n\
+Give an expression for the address of the file's shared object file header.",
+           &cmdlist);
+
+}
diff --git a/gdb/testsuite/gdb.ada/gnat_ada.gin b/gdb/testsuite/gdb.ada/gnat_ada.gin
new file mode 100644 (file)
index 0000000..23cd558
--- /dev/null
@@ -0,0 +1,27 @@
+--  Copyright 2004 Free Software Foundation, Inc.
+--
+--  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.
+
+--  This project file allows us to control the location where the
+--  compilation artifacts produced when building the Ada examples
+--  are stored.
+
+project Gnat_Ada is
+
+   for Source_Dirs use ("@srcdir@");
+   --  No need to set the Object_Dir, it is set to "." by default
+   --  (which means the same directory as this project file).
+
+end Gnat_Ada;
diff --git a/gdb/testsuite/gdb.arch/e500-prologue.c b/gdb/testsuite/gdb.arch/e500-prologue.c
new file mode 100644 (file)
index 0000000..f9e83da
--- /dev/null
@@ -0,0 +1,54 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.  */
+
+void arg_passing_test2 (void);
+
+int
+main (void)
+{
+  arg_passing_test2 ();
+  return 0;
+}
+
+
+/* Asm for procedure arg_passing_test2.
+
+   The challenge here is getting past the 'mr 0,3' and 'stb'
+   instructions.  */
+
+asm (" .section        \".text\"\n"
+     " .align 2\n"
+     " .globl arg_passing_test2\n"
+     " .type   arg_passing_test2, @function\n"
+     "arg_passing_test2:\n"
+     " stwu 1,-64(1)\n"
+     " stw 31,60(1)\n"
+     " mr 31,1\n"
+     " mr 0,3\n"
+     " evstdd 4,16(31)\n"
+     " stw 5,24(31)\n"
+     " stw 7,32(31)\n"
+     " stw 8,36(31)\n"
+     " stw 9,40(31)\n"
+     " stb 0,8(31)\n"
+     " lwz 11,0(1)\n"
+     " lwz 31,-4(11)\n"
+     " mr 1,11\n"
+     " blr\n"
+     " .size   arg_passing_test2, .-arg_passing_test2\n");
diff --git a/gdb/testsuite/gdb.arch/e500-prologue.exp b/gdb/testsuite/gdb.arch/e500-prologue.exp
new file mode 100644 (file)
index 0000000..06dec9f
--- /dev/null
@@ -0,0 +1,82 @@
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# 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.  
+#
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+# Test PowerPC E500 prologue analyzer.
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "powerpc-*"] then {
+    verbose "Skipping powerpc E500 prologue tests."
+    return
+}
+
+set testfile "e500-prologue"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } {
+    unsupported "Testcase compile failed."
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Insert a breakpoint in FUNCTION and verifies that the breakpoint was
+# inserted at the expected location.  EXPECTED_LOCATION should be an
+# offset relative to the function start address.
+proc insert_breakpoint {function expected_location} {
+    global gdb_prompt
+    global expect_out
+    global hex
+    
+    set address ""
+
+    # Insert a breakpoint using the given function name, and extract
+    # the breakpoint address for the output.
+    gdb_test_multiple "break $function" "set breakpoint in $function" {
+        -re "Breakpoint 1 at ($hex).*$gdb_prompt $" {
+            set address $expect_out(1,string)
+        }
+        default {
+            fail "set breakpoint in $function"
+        }
+    }
+
+    # If we managed to get the breakpoing address, then check that
+    # we inserted it at the expected location by examining the
+    # instruction at that address (we're not interested in the insn
+    # itself, but rather at the address printed at the begining of
+    # the instruction).
+    if { $address != "" } then {
+       gdb_test "x /i $address" \
+                ".*<$function\\+$expected_location>.*" \
+                "check $function breakpoint address"
+    } else {
+       fail "unable to compute breakpoint address"
+    }
+
+}
+
+insert_breakpoint "arg_passing_test2" 40
diff --git a/gdb/testsuite/gdb.arch/i386-cpuid.h b/gdb/testsuite/gdb.arch/i386-cpuid.h
new file mode 100644 (file)
index 0000000..067b22f
--- /dev/null
@@ -0,0 +1,77 @@
+/* Helper file for i386 platform.  Runtime check for MMX/SSE/SSE2 support.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+/* Used by 20020523-2.c and i386-sse-6.c, and possibly others.  */
+/* Plagarized from 20020523-2.c.  */
+/* Plagarized from gcc.  */
+
+#define bit_CMOV (1 << 15)
+#define bit_MMX (1 << 23)
+#define bit_SSE (1 << 25)
+#define bit_SSE2 (1 << 26)
+
+#ifndef NOINLINE
+#define NOINLINE __attribute__ ((noinline))
+#endif
+
+unsigned int i386_cpuid (void) NOINLINE;
+
+unsigned int NOINLINE
+i386_cpuid (void)
+{
+  int fl1, fl2;
+
+#ifndef __x86_64__
+  /* See if we can use cpuid.  On AMD64 we always can.  */
+  __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+          "pushl %0; popfl; pushfl; popl %0; popfl"
+          : "=&r" (fl1), "=&r" (fl2)
+          : "i" (0x00200000));
+  if (((fl1 ^ fl2) & 0x00200000) == 0)
+    return (0);
+#endif
+
+  /* Host supports cpuid.  See if cpuid gives capabilities, try
+     CPUID(0).  Preserve %ebx and %ecx; cpuid insn clobbers these, we
+     don't need their CPUID values here, and %ebx may be the PIC
+     register.  */
+#ifdef __x86_64__
+  __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
+          : "=a" (fl1) : "0" (0) : "rdx", "cc");
+#else
+  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+          : "=a" (fl1) : "0" (0) : "edx", "cc");
+#endif
+  if (fl1 == 0)
+    return (0);
+
+  /* Invoke CPUID(1), return %edx; caller can examine bits to
+     determine what's supported.  */
+#ifdef __x86_64__
+  __asm__ ("pushq %%rcx; pushq %%rbx; cpuid; popq %%rbx; popq %%rcx"
+          : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+#else
+  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
+          : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
+#endif
+
+  return fl2;
+}
diff --git a/gdb/testsuite/gdb.arch/i386-sse.c b/gdb/testsuite/gdb.arch/i386-sse.c
new file mode 100644 (file)
index 0000000..496721c
--- /dev/null
@@ -0,0 +1,90 @@
+/* Test program for SSE registers.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include <stdio.h>
+#include "i386-cpuid.h"
+
+typedef struct {
+  float f[4];
+} v4sf_t;
+
+
+v4sf_t data[8] =
+  {
+    { {  0.0, 0.25, 0.50, 0.75 } },
+    { {  1.0, 1.25, 1.50, 1.75 } },
+    { {  2.0, 2.25, 2.50, 2.75 } },
+    { {  3.0, 3.25, 3.50, 3.75 } },
+    { {  4.0, 4.25, 4.50, 4.75 } },
+    { {  5.0, 5.25, 5.50, 5.75 } },
+    { {  6.0, 6.25, 6.50, 6.75 } },
+    { {  7.0, 7.25, 7.50, 7.75 } },
+  };
+
+
+int
+have_sse (void)
+{
+  int edx = i386_cpuid ();
+
+  if (edx & bit_SSE)
+    return 1;
+  else
+    return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  if (have_sse ())
+    {
+      asm ("movaps 0(%0), %%xmm0\n\t"
+           "movaps 16(%0), %%xmm1\n\t"
+           "movaps 32(%0), %%xmm2\n\t"
+           "movaps 48(%0), %%xmm3\n\t"
+           "movaps 64(%0), %%xmm4\n\t"
+           "movaps 80(%0), %%xmm5\n\t"
+           "movaps 96(%0), %%xmm6\n\t"
+           "movaps 112(%0), %%xmm7\n\t"
+           : /* no output operands */
+           : "r" (data) 
+           : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7");
+
+      puts ("Hi!"); /* first breakpoint here */
+
+      asm (
+           "movaps %%xmm0, 0(%0)\n\t"
+           "movaps %%xmm1, 16(%0)\n\t"
+           "movaps %%xmm2, 32(%0)\n\t"
+           "movaps %%xmm3, 48(%0)\n\t"
+           "movaps %%xmm4, 64(%0)\n\t"
+           "movaps %%xmm5, 80(%0)\n\t"
+           "movaps %%xmm6, 96(%0)\n\t"
+           "movaps %%xmm7, 112(%0)\n\t"
+           : /* no output operands */
+           : "r" (data) 
+           : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7");
+
+      puts ("Bye!"); /* second breakpoint here */
+    }
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/i386-sse.exp b/gdb/testsuite/gdb.arch/i386-sse.exp
new file mode 100644 (file)
index 0000000..702ee71
--- /dev/null
@@ -0,0 +1,92 @@
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "i?86-*-*"] then {
+    verbose "Skipping i386 SSE tests."
+    return
+}
+
+set testfile "i386-sse"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    unsupported "compiler does not support SSE"
+    return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+send_gdb "print have_sse ()\r"
+gdb_expect {
+    -re ".. = 1\r\n$gdb_prompt " {
+        pass "check whether processor supports SSE"
+    }
+    -re ".. = 0\r\n$gdb_prompt " {
+        verbose "processor does not support SSE; skipping SSE tests"
+        return
+    }
+    -re ".*$gdb_prompt $" {
+        fail "check whether processor supports SSE"
+    }
+    timeout {
+        fail "check whether processor supports SSE (timeout)"
+    }
+}
+
+gdb_test "break [gdb_get_line_number "first breakpoint here"]" \
+         "Breakpoint .* at .*i386-sse.c.*" \
+         "set breakpoint in main"
+gdb_continue_to_breakpoint "continue to first breakpoint in main"
+
+foreach r {0 1 2 3 4 5 6 7} {
+    gdb_test "print \$xmm$r.v4_float" \
+        ".. = \\{$r, $r.25, $r.5, $r.75\\}.*" \
+        "check contents of %xmm$r"
+}
+
+foreach r {0 1 2 3 4 5 6 7} {
+    gdb_test "set var \$xmm$r.v4_float\[0\] = $r + 10" "" "set %xmm$r"
+}
+
+gdb_test "break [gdb_get_line_number "second breakpoint here"]" \
+         "Breakpoint .* at .*i386-sse.c.*" \
+         "set breakpoint in main"
+gdb_continue_to_breakpoint "continue to second breakpoint in main"
+
+foreach r {0 1 2 3 4 5 6 7} {
+    gdb_test "print data\[$r\]" \
+        ".. = \\{f = \\{[expr $r + 10], $r.25, $r.5, $r.75\\}\\}.*" \
+        "check contents of data\[$r\]"
+}
diff --git a/gdb/testsuite/gdb.arch/powerpc-aix-prologue.c b/gdb/testsuite/gdb.arch/powerpc-aix-prologue.c
new file mode 100644 (file)
index 0000000..ee31b49
--- /dev/null
@@ -0,0 +1,55 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.  */
+
+void li_stw (void);
+
+int
+main (void)
+{
+  li_stw ();
+  return 0;
+}
+
+/* Asm for procedure li_stw().
+
+   The purpose of this function is to verify that GDB does not
+   include the li insn as part of the function prologue (only part
+   of the prologue if part of a pair of insns saving vector registers).
+   Similarly, GDB should not include the stw insn following the li insn,
+   because the source register is not used for parameter passing.  */
+
+
+asm ("        .csect .text[PR]\n"
+     "        .align 2\n"
+     "        .lglobl .li_stw\n"
+     "        .csect li_stw[DS]\n"
+     "li_stw:\n"
+     "        .long .li_stw, TOC[tc0], 0\n"
+     "        .csect .text[PR]\n"
+     ".li_stw:\n"
+     "        stw 31,-4(1)\n"
+     "        stwu 1,-48(1)\n"
+     "        mr 31,1\n"
+     "        stw 11,24(31)\n"
+     "        li 0,8765\n"
+     "        stw 0,28(31)\n"
+     "        lwz 1,0(1)\n"
+     "        lwz 31,-4(1)\n"
+     "        blr\n");
+
diff --git a/gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp b/gdb/testsuite/gdb.arch/powerpc-aix-prologue.exp
new file mode 100644 (file)
index 0000000..76e3c27
--- /dev/null
@@ -0,0 +1,82 @@
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# 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.  
+#
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+# Test rs6000 prologue analyzer.
+
+set prms_id 0
+set bug_id 0
+
+if ![istarget "powerpc-*-aix*"] then {
+    verbose "Skipping powerpc-aix prologue tests."
+    return
+}
+
+set testfile "powerpc-aix-prologue"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {}] != "" } {
+    unsupported "Testcase compile failed."
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Insert a breakpoint in FUNCTION and verifies that the breakpoint was
+# inserted at the expected location.  EXPECTED_LOCATION should be an
+# offset relative to the function start address.
+proc insert_breakpoint {function expected_location} {
+    global gdb_prompt
+    global expect_out
+    global hex
+    
+    set address ""
+
+    # Insert a breakpoint using the given function name, and extract
+    # the breakpoint address for the output.
+    gdb_test_multiple "break $function" "set breakpoint in $function" {
+        -re "Breakpoint 1 at ($hex).*$gdb_prompt $" {
+            set address $expect_out(1,string)
+        }
+        default {
+            fail "set breakpoint in $function"
+        }
+    }
+
+    # If we managed to get the breakpoing address, then check that
+    # we inserted it at the expected location by examining the
+    # instruction at that address (we're not interested in the insn
+    # itself, but rather at the address printed at the begining of
+    # the instruction).
+    if { $address != "" } then {
+       gdb_test "x /i $address" \
+                ".*<$function\\+$expected_location>.*" \
+                "check $function breakpoint address"
+    } else {
+       fail "unable to compute breakpoint address"
+    }
+
+}
+
+insert_breakpoint "li_stw" 12
diff --git a/gdb/testsuite/gdb.asm/pa.inc b/gdb/testsuite/gdb.asm/pa.inc
new file mode 100644 (file)
index 0000000..d53336e
--- /dev/null
@@ -0,0 +1,44 @@
+       comment "subroutine prologue"
+       .macro gdbasm_enter
+       stw %rp, -20(%sp)
+       copy %r3, %r1
+       copy %sp, %r3
+       stwm %r1, 64(%sp)
+       .endm
+
+       comment "subroutine epilogue"
+       .macro gdbasm_leave
+       ldw -20(%r3), %rp
+       bv %r0(%rp)
+       ldwm -64(%sp), %r3
+       .endm
+
+       .macro gdbasm_call subr
+       bl      \subr , %rp
+       nop
+       .endm
+
+       .macro gdbasm_several_nops
+       nop
+       nop
+       nop
+       nop
+       .endm
+
+       comment "exit (0)"
+       .macro gdbasm_exit0
+       comment "Don't know how to exit, but this will certainly halt..."
+       ldw     0(%r0), %r1
+       .endm
+
+       comment "crt0 startup"
+       .macro gdbasm_startup
+       .align 4
+       .endm
+
+       comment "Declare a data variable"
+       .macro gdbasm_datavar name value
+       .data
+\name:
+       .long   \value
+       .endm
diff --git a/gdb/testsuite/gdb.base/call-sc.c b/gdb/testsuite/gdb.base/call-sc.c
new file mode 100644 (file)
index 0000000..70ae87f
--- /dev/null
@@ -0,0 +1,83 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+*/
+
+/* Useful abreviations.  */
+typedef void t;
+typedef char tc;
+typedef short ts;
+typedef int ti;
+typedef long tl;
+typedef long long tll;
+typedef float tf;
+typedef double td;
+typedef long double tld;
+typedef enum { e = '1' } te;
+
+/* Force the type of each field.  */
+#ifndef T
+typedef t T;
+#endif
+
+T foo = '1', L;
+
+T fun()
+{
+  return foo;  
+}
+
+#ifdef PROTOTYPES
+void Fun(T foo)
+#else
+void Fun(foo)
+     T foo;
+#endif
+{
+  L = foo;
+}
+
+zed ()
+{
+  L = 'Z';
+}
+
+int main()
+{
+#ifdef usestubs
+  set_debug_traps();
+  breakpoint();
+#endif
+  int i;
+
+  Fun(foo);    
+
+  /* An infinite loop that first clears all the variables and then
+     calls the function.  This "hack" is to make re-testing easier -
+     "advance fun" is guaranteed to have always been preceeded by a
+     global variable clearing zed call.  */
+
+  zed ();
+  while (1)
+    {
+      L = fun ();      
+      zed ();
+    }
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/call-sc.exp b/gdb/testsuite/gdb.base/call-sc.exp
new file mode 100644 (file)
index 0000000..01a9f15
--- /dev/null
@@ -0,0 +1,500 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Test "return", "finish", and "call" of functions that a scalar (int,
+# float, enum) and/or take a single scalar parameter.
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Some targets can't call functions, so don't even bother with this
+# test.
+
+if [target_info exists gdb,cannot_call_functions] {
+    setup_xfail "*-*-*"
+    fail "This target can not call functions"
+    continue
+}
+
+set testfile "call-sc"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Create and source the file that provides information about the
+# compiler used to compile the test case.
+
+if [get_compiler_info ${binfile}] {
+    return -1;
+}
+
+# Use the file name, compiler and tuples to set up any needed KFAILs.
+
+proc setup_kfails { file tuples bug } {
+    global testfile
+    if [string match $file $testfile] {
+       foreach f $tuples { setup_kfail $f $bug }
+    }
+}
+
+proc setup_compiler_kfails { file compiler format tuples bug } {
+    global testfile
+    if {[string match $file $testfile] && [test_compiler_info $compiler]  && [test_debug_format $format]} {
+       foreach f $tuples { setup_kfail $f $bug }
+    }
+}
+
+# Compile a variant of scalars.c using TYPE to specify the type of the
+# parameter and return-type.  Run the compiled program up to "main".
+# Also updates the global "testfile" to reflect the most recent build.
+
+proc start_scalars_test { type } {
+    global testfile
+    global srcfile
+    global binfile
+    global objdir
+    global subdir
+    global srcdir
+    global gdb_prompt
+    global expect_out
+
+    # Create the additional flags
+    set flags "debug additional_flags=-DT=${type}"
+    set testfile "call-sc-${type}"
+
+    set binfile ${objdir}/${subdir}/${testfile}
+    if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags}"] != "" } {
+       # built the second test case since we can't use prototypes
+       warning "Prototypes not supported, rebuilding with -DNO_PROTOTYPES"
+       if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "${flags} additional_flags=-DNO_PROTOTYPES"] != "" } {
+           gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+       }
+    }
+
+    # Start with a fresh gdb.
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load ${binfile}
+
+    # Make certain that the output is consistent
+    gdb_test "set print sevenbit-strings" "" \
+           "set print sevenbit-strings; ${testfile}"
+    gdb_test "set print address off" "" \
+           "set print address off; ${testfile}"
+    gdb_test "set width 0" "" \
+           "set width 0; ${testfile}"
+
+    # Advance to main
+    if { ![runto_main] } then {
+       gdb_suppress_tests;
+    }
+
+    # Get the debug format
+    get_debug_format
+
+    # check that type matches what was passed in
+    set test "ptype; ${testfile}"
+    set foo_t "xxx"
+    gdb_test_multiple "ptype ${type}" "${test}" {
+       -re "type = (\[^\r\n\]*)\r\n$gdb_prompt $" {
+           set foo_t "$expect_out(1,string)"
+           pass "$test (${foo_t})"
+       }
+    }
+    gdb_test "ptype foo" "type = ${foo_t}" "ptype foo; ${testfile} $expect_out(1,string)"
+}
+
+
+# Given N (0..25), return the corresponding alphabetic letter in lower
+# or upper case.  This is ment to be i18n proof.
+
+proc i2a { n } {
+    return [string range "abcdefghijklmnopqrstuvwxyz" $n $n]
+}
+
+proc I2A { n } {
+    return [string toupper [i2a $n]]
+}
+
+
+# Use the file name, compiler and tuples to set up any needed KFAILs.
+
+proc setup_kfails { file tuples bug } {
+    global testfile
+    if [string match $file $testfile] {
+       foreach f $tuples { setup_kfail $f $bug }
+    }
+}
+
+proc setup_compiler_kfails { file compiler format tuples bug } {
+    global testfile
+    if {[string match $file $testfile] && [test_compiler_info $compiler]  && [test_debug_format $format]} {
+       foreach f $tuples { setup_kfail $f $bug }
+    }
+}
+
+# Test GDB's ability to make inferior function calls to functions
+# returning (or passing) in a single scalar.
+
+# start_scalars_test() will have previously built a program with a
+# specified scalar type.  To ensure robustness of the output, "p/c" is
+# used.
+
+# This tests the code paths "which return-value convention?" and
+# "extract return-value from registers" called by "infcall.c".
+
+proc test_scalar_calls { } {
+    global testfile
+    global gdb_prompt
+
+    # Check that GDB can always extract a scalar-return value from an
+    # inferior function call.  Since GDB always knows the location of
+    # an inferior function call's return value these should never fail
+    
+    # Implemented by calling the parameterless function "fun" and then
+    # examining the return value printed by GDB.
+
+    set tests "call ${testfile}"
+
+    # Call fun, checking the printed return-value.
+    gdb_test "p/c fun()" "= 49 '1'" "p/c fun(); ${tests}"
+
+    # Check that GDB can always pass a structure to an inferior function.
+    # This test can never fail.
+
+    # Implemented by calling the one parameter function "Fun" which
+    # stores its parameter in the global variable "L".  GDB then
+    # examining that global to confirm that the value is as expected.
+
+    gdb_test "call Fun(foo)" "" "call Fun(foo); ${tests}"
+    gdb_test "p/c L" " = 49 '1'" "p/c L; ${tests}"
+}
+
+# Test GDB's ability to both return a function (with "return" or
+# "finish") and correctly extract/store any corresponding
+# return-value.
+
+# Check that GDB can consistently extract/store structure return
+# values.  There are two cases - returned in registers and returned in
+# memory.  For the latter case, the return value can't be found and a
+# failure is "expected".  However GDB must still both return the
+# function and display the final source and line information.
+
+# N identifies the number of elements in the struct that will be used
+# for the test case.  FAILS is a list of target tuples that will fail
+# this test.
+
+# This tests the code paths "which return-value convention?", "extract
+# return-value from registers", and "store return-value in registers".
+# Unlike "test struct calls", this test is expected to "fail" when the
+# return-value is in memory (GDB can't find the location).  The test
+# is in three parts: test "return"; test "finish"; check that the two
+# are consistent.  GDB can sometimes work for one command and not the
+# other.
+
+proc test_scalar_returns { } {
+    global gdb_prompt
+    global testfile
+
+    set tests "return ${testfile}"
+
+
+    # Check that "return" works.
+
+    # GDB must always force the return of a function that has
+    # a struct result.  Dependant on the ABI, it may, or may not be
+    # possible to store the return value in a register.
+
+    # The relevant code looks like "L{n} = fun{n}()".  The test forces
+    # "fun{n}" to "return" with an explicit value.  Since that code
+    # snippet will store the the returned value in "L{n}" the return
+    # is tested by examining "L{n}".  This assumes that the
+    # compiler implemented this as fun{n}(&L{n}) and hence that when
+    # the value isn't stored "L{n}" remains unchanged.  Also check for
+    # consistency between this and the "finish" case.
+
+    # Get into a call of fun
+    gdb_test "advance fun" \
+           "fun .*\[\r\n\]+\[0-9\].*return foo.*" \
+           "advance to fun for return; ${tests}"
+
+    # Check that the program invalidated the relevant global.
+    gdb_test "p/c L" " = 90 'Z'" "zed L for return; ${tests}"
+
+    # Force the "return".  This checks that the return is always
+    # performed, and that GDB correctly reported this to the user.
+    # GDB 6.0 and earlier, when the return-value's location wasn't
+    # known, both failed to print a final "source and line" and misplaced
+    # the frame ("No frame").
+
+    # The test is writen so that it only reports one FAIL/PASS for the
+    # entire operation.  The value returned is checked further down.
+    # "return_value_unknown", if non-empty, records why GDB realised
+    # that it didn't know where the return value was.
+
+    set test "return foo; ${tests}"
+    set return_value_unknown 0
+    set return_value_unimplemented 0
+    gdb_test_multiple "return foo" "${test}" {
+       -re "The location" {
+           # Ulgh, a struct return, remember this (still need prompt).
+           set return_value_unknown 1
+           exp_continue
+       }
+       -re "A structure or union" {
+           # Ulgh, a struct return, remember this (still need prompt).
+           set return_value_unknown 1
+           # Double ulgh.  Architecture doesn't use return_value and
+           # hence hasn't implemented small structure return.
+           set return_value_unimplemented 1
+           exp_continue
+       }
+       -re "Make fun return now.*y or n. $" {
+           gdb_test_multiple "y" "${test}" {
+               -re "L *= fun.*${gdb_prompt} $" {
+                   # Need to step off the function call
+                   gdb_test "next" "zed.*" "${test}"
+               }
+               -re "zed \\(\\);.*$gdb_prompt $" {
+                   pass "${test}"
+               }
+           }
+       }
+    }
+
+    # If the previous test did not work, the program counter might
+    # still be inside foo() rather than main().  Make sure the program
+    # counter is is main().
+    #
+    # This happens on ppc64 GNU/Linux with gcc 3.4.1 and a buggy GDB
+
+    set test "return foo; synchronize pc to main()"
+    for {set loop_count 0} {$loop_count < 2} {incr loop_count} {
+      gdb_test_multiple "backtrace 1" $test {
+        -re "#0.*main \\(\\).*${gdb_prompt} $" {
+          pass $test
+          set loop_count 2
+        }
+        -re "#0.*fun \\(\\).*${gdb_prompt} $" {
+          if {$loop_count < 1} {
+            gdb_test "finish" ".*" ""
+          } else {
+            fail $test
+            set loop_count 2
+          }
+        }
+      }
+    }
+
+    # Check that the return-value is as expected.  At this stage we're
+    # just checking that GDB has returned a value consistent with
+    # "return_value_unknown" set above.
+
+    set test "value foo returned; ${tests}"
+    gdb_test_multiple "p/c L" "${test}" {
+       -re " = 49 '1'.*${gdb_prompt} $" {
+           if $return_value_unknown {
+               # This contradicts the above claim that GDB didn't
+               # know the location of the return-value.
+               fail "${test}"
+           } else {
+               pass "${test}"
+           }
+       }
+       -re " = 90 .*${gdb_prompt} $" {
+           if $return_value_unknown {
+               # The struct return case.  Since any modification
+               # would be by reference, and that can't happen, the
+               # value should be unmodified and hence Z is expected.
+               # Is this a reasonable assumption?
+               pass "${test}"
+           } else {
+               # This contradicts the above claim that GDB knew
+               # the location of the return-value.
+               fail "${test}"
+           }
+       }
+       -re ".*${gdb_prompt} $" {
+           if $return_value_unimplemented {
+               # What a suprize.  The architecture hasn't implemented
+               # return_value, and hence has to fail.
+               kfail "$test" gdb/1444
+           } else {
+               fail "$test"
+           }
+       }
+    }  
+    
+    # Check that a "finish" works.
+
+    # This is almost but not quite the same as "call struct funcs".
+    # Architectures can have subtle differences in the two code paths.
+
+    # The relevant code snippet is "L{n} = fun{n}()".  The program is
+    # advanced into a call to  "fun{n}" and then that function is
+    # finished.  The returned value that GDB prints, reformatted using
+    # "p/c", is checked.
+
+    # Get into "fun()".
+    gdb_test "advance fun" \
+           "fun .*\[\r\n\]+\[0-9\].*return foo.*" \
+           "advance to fun for finish; ${tests}"
+
+    # Check that the program invalidated the relevant global.
+    gdb_test "p/c L" " = 90 'Z'" "zed L for finish; ${tests}"
+
+    # Finish the function, set 'finish_value_unknown" to non-empty if the
+    # return-value was not found.
+    set test "finish foo; ${tests}"
+    set finish_value_unknown 0
+    gdb_test_multiple "finish" "${test}" {
+       -re "Value returned is .*${gdb_prompt} $" {
+           pass "${test}"
+       }
+       -re "Cannot determine contents.*${gdb_prompt} $" {
+           # Expected bad value.  For the moment this is ok.
+           set finish_value_unknown 1
+           pass "${test}"
+       }
+    }
+
+    # Re-print the last (return-value) using the more robust
+    # "p/c".  If no return value was found, the 'Z' from the previous
+    # check that the variable was cleared, is printed.
+    set test "value foo finished; ${tests}"
+    gdb_test_multiple "p/c" "${test}" {
+       -re " = 49 '1'\[\r\n\]+${gdb_prompt} $" {
+           if $finish_value_unknown {
+               # This contradicts the above claim that GDB didn't
+               # know the location of the return-value.
+               fail "${test}"
+           } else {
+               pass "${test}"
+           }
+       }
+       -re " = 90 'Z'\[\r\n\]+${gdb_prompt} $" {
+           # The value didn't get found.  This is "expected".
+           if $finish_value_unknown {
+               pass "${test}"
+           } else {
+               # This contradicts the above claim that GDB did
+               # know the location of the return-value.
+               fail "${test}"
+           }
+       }
+    }
+
+    # Finally, check that "return" and finish" have consistent
+    # behavior.
+
+    # Since both "return" and "finish" use equivalent "which
+    # return-value convention" logic, both commands should have
+    # identical can/can-not find return-value messages.
+
+    # Note that since "call" and "finish" use common code paths, a
+    # failure here is a strong indicator of problems with "store
+    # return-value" code paths.  Suggest looking at "return_value"
+    # when investigating a fix.
+
+    set test "return and finish use same convention; ${tests}"
+    if {$finish_value_unknown == $return_value_unknown} {
+       pass "${test}"
+    } else {
+       kfail gdb/1444 "${test}"
+    }
+}
+
+# ABIs pass anything >8 or >16 bytes in memory but below that things
+# randomly use register and/and structure conventions.  Check all
+# possible sized char scalars in that range.  But only a restricted
+# range of the other types.
+
+# NetBSD/PPC returns "unnatural" (3, 5, 6, 7) sized scalars in memory.
+
+# d10v is weird. 5/6 byte scalars go in memory.  2 or more char
+# scalars go in memory.  Everything else is in a register!
+
+# Test every single char struct from 1..17 in size.  This is what the
+# original "scalars" test was doing.
+
+start_scalars_test tc
+test_scalar_calls
+test_scalar_returns
+
+
+# Let the fun begin.
+
+# Assuming that any integer struct larger than 8 bytes goes in memory,
+# come up with many and varied combinations of a return struct.  For
+# "struct calls" test just beyond that 8 byte boundary, for "struct
+# returns" test up to that boundary.
+
+# For floats, assumed that up to two struct elements can be stored in
+# floating point registers, regardless of their size.
+
+# The approx size of each structure it is computed assumed that tc=1,
+# ts=2, ti=4, tl=4, tll=8, tf=4, td=8, tld=16, and that all fields are
+# naturally aligned.  Padding being added where needed.  Note that
+# these numbers are just approx, the d10v has ti=2, a 64-bit has has
+# tl=8.
+
+# Approx size: 2, 4, ...
+start_scalars_test ts
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test ti
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test tl
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 8, 16, ...
+start_scalars_test tll
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test tf
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 8, 16, ...
+start_scalars_test td
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 16, 32, ...
+start_scalars_test tld
+test_scalar_calls
+test_scalar_returns
+
+# Approx size: 4, 8, ...
+start_scalars_test te
+test_scalar_calls
+test_scalar_returns
+
+return 0
diff --git a/gdb/testsuite/gdb.base/lineinc.c b/gdb/testsuite/gdb.base/lineinc.c
new file mode 100644 (file)
index 0000000..91784e7
--- /dev/null
@@ -0,0 +1,30 @@
+/* The following is written to tickle a specific bug in the macro
+   table code (now hopefully fixed), which doesn't insert new included
+   files in the #including file's list in the proper place.  They
+   should be sorted by the number of the line which #included them, in
+   increasing order, but the sense of the comparison was reversed, so
+   the list ends up being built backwards.  This isn't a problem by
+   itself, but the code to pick new, non-conflicting line numbers for
+   headers alleged to be #included at the same line as some other
+   header assumes that the list's line numbers are in ascending order.
+
+   So, given the following input, lineinc1.h gets added to lineinc.c's
+   #inclusion list first, at line 10.  When the debug info reader
+   tries to add lineinc2.h at line 10 as well, the code will notice the
+   duplication --- since there's only one extant element in the list,
+   it'll find it --- and insert it after lineinc1.h, with line 11.
+   Since the code is putting the list in order of descending
+   #inclusion line number, the list is now out of order.  When we try
+   to #include lineinc3.h at line 11, we won't notice the duplication.  */
+
+#line 10
+#include "lineinc1.h"
+#line 10
+#include "lineinc2.h"
+#line 11
+#include "lineinc3.h"
+
+int
+main (int argc, char **argv)
+{
+}
diff --git a/gdb/testsuite/gdb.base/lineinc.exp b/gdb/testsuite/gdb.base/lineinc.exp
new file mode 100644 (file)
index 0000000..4707ce5
--- /dev/null
@@ -0,0 +1,126 @@
+# Test macro handling of #included files.
+# Copyright 2003 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# The test program lineinc.c contains a mix of #line directives and
+# #include directives that will cause the compiler to attribute more
+# than one #inclusion to the same source line.  You can get similar
+# effects using things like GCC's '-imacros' flag.
+#
+# Compiling lineinc.c with Dwarf 2 macro information will produce
+# something like this:
+# 
+#     $ gcc -g3 lineinc.c -o lineinc
+#     $ readelf -wml lineinc
+#     ...
+#      The File Name Table:
+#       Entry  Dir     Time    Size    Name
+#       1      0       0       0       lineinc.c
+#       2      0       0       0       lineinc1.h
+#       3      0       0       0       lineinc2.h
+#       4      0       0       0       lineinc3.h
+#     ...
+#     Contents of the .debug_macinfo section:
+#     
+#      DW_MACINFO_start_file - lineno: 0 filenum: 1
+#      DW_MACINFO_define - lineno : 1 macro : __VERSION__ "3.2 20020903 (Red Hat Linux 8.0 3.2-7)"
+#      DW_MACINFO_define - lineno : 2 macro : __USER_LABEL_PREFIX__ 
+#     ...
+#      DW_MACINFO_define - lineno : 1 macro : __i386__ 1
+#      DW_MACINFO_define - lineno : 1 macro : __tune_i386__ 1
+#      DW_MACINFO_start_file - lineno: 10 filenum: 2
+#      DW_MACINFO_define - lineno : 1 macro : FOO 1
+#      DW_MACINFO_end_file
+#      DW_MACINFO_start_file - lineno: 10 filenum: 3
+#      DW_MACINFO_undef - lineno : 1 macro : FOO
+#      DW_MACINFO_define - lineno : 2 macro : FOO 2
+#      DW_MACINFO_end_file
+#      DW_MACINFO_start_file - lineno: 11 filenum: 4
+#      DW_MACINFO_undef - lineno : 1 macro : FOO
+#      DW_MACINFO_define - lineno : 2 macro : FOO 3
+#      DW_MACINFO_end_file
+#      DW_MACINFO_end_file
+#     $   
+#
+# Note how the inclusions of lineinc1.h and lineinc2.h are both
+# attributed to line 10 of lineinc.c, and the #inclusion of lineinc3.h
+# is attributed to line 11.  This is all correct, given the #line
+# directives in lineinc.c.
+#
+# Dwarf 2 macro information doesn't contain enough information to
+# allow GDB to figure out what's really going on here --- it makes no
+# mention of the #line directives --- so we just try to cope as best
+# we can.  If the macro table were to attribute more than one
+# #inclusion to the same source line, then GDB wouldn't be able to
+# tell which #included file's #definitions and #undefinitions come
+# first, so it can't tell which #definitions are in scope following
+# all the #inclusions.  To cope with this, GDB puts all the files
+# #included by a given source file in a list sorted by the line at
+# which they were #included; this gives GDB the chance to detect
+# multiple #inclusions at the same line, complain, and assign
+# distinct, albiet incorrect, line numbers to each #inclusion.
+#
+# However, at one point GDB was sorting the list in reverse order,
+# while the code to assign new, distinct line numbers assumed it was
+# sorted in ascending order; GDB would get an internal error trying to
+# read the above debugging info.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "lineinc"
+set binfile ${objdir}/${subdir}/${testfile}
+
+
+if {[gdb_compile "${srcdir}/${subdir}/${testfile}.c" ${binfile} executable {debug}] != ""} {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Any command that causes GDB to read the debugging info for the
+# lineinc.c compilation unit will do here.
+set test_name "tolerate macro info with multiple #inclusions per line"
+gdb_test_multiple "break main" $test_name {
+    -re "Breakpoint 1 at 0x.*: file .*lineinc.c.*\\.\r\n${gdb_prompt}" {
+        pass $test_name
+    }
+    -re ".*internal-error:.*.y or n. " {
+        fail $test_name
+        send_gdb "y\n"
+        gdb_expect {
+            -re ".*.y or n. " {
+                send_gdb "n\n"
+                exp_continue
+            }
+            -re "$gdb_prompt" {
+            }                
+            timeout {
+                fail "$test_name (timeout)"
+            }
+        }
+    }
+}
diff --git a/gdb/testsuite/gdb.base/lineinc1.h b/gdb/testsuite/gdb.base/lineinc1.h
new file mode 100644 (file)
index 0000000..8523d58
--- /dev/null
@@ -0,0 +1 @@
+#define FOO 1
diff --git a/gdb/testsuite/gdb.base/lineinc2.h b/gdb/testsuite/gdb.base/lineinc2.h
new file mode 100644 (file)
index 0000000..ee800ba
--- /dev/null
@@ -0,0 +1,2 @@
+#undef FOO
+#define FOO 2
diff --git a/gdb/testsuite/gdb.base/lineinc3.h b/gdb/testsuite/gdb.base/lineinc3.h
new file mode 100644 (file)
index 0000000..be3bb54
--- /dev/null
@@ -0,0 +1,2 @@
+#undef FOO
+#define FOO 3
diff --git a/gdb/testsuite/gdb.base/sep-proc.c b/gdb/testsuite/gdb.base/sep-proc.c
new file mode 100644 (file)
index 0000000..0fbb17a
--- /dev/null
@@ -0,0 +1,26 @@
+/* This file is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+void
+say_hello (void)
+{
+  printf ("Hello world.\n");
+}
diff --git a/gdb/testsuite/gdb.base/sep.c b/gdb/testsuite/gdb.base/sep.c
new file mode 100644 (file)
index 0000000..4402bd8
--- /dev/null
@@ -0,0 +1,35 @@
+/* This file is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <stdio.h>
+
+/* Include a .c file.  This is usually considered bad practice in C,
+   but this emulate a practice which is common in other languages.
+   One such language is Ada and its concept of "separates", for instance.  */
+#include "sep-proc.c"
+
+int
+main (void)
+{
+  say_hello ();
+  return 0;
+}
+
diff --git a/gdb/testsuite/gdb.base/sep.exp b/gdb/testsuite/gdb.base/sep.exp
new file mode 100644 (file)
index 0000000..7a7c22a
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# 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.  
+#
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile "sep"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Try to display the source code inside a file which is included by
+# another source file.  The purpose of this test is to verify that
+# this operation works, even before we have loaded full symbols for
+# that file (by doing a "break say_hello" for instance).
+#
+# We just check that the command succeeds, so no need to match the
+# complete exact output.  Simply verifying that we get procedure
+# say_hello is good enough, and avoid unnecessary failures is someone
+# decides later to reformat sep-proc.c.
+
+gdb_test "list sep-proc.c:23" \
+         "void.*say_hello.*" \
+         "list using location inside included file"
+
+# Try the same, but this time with a breakpoint.  We need to exit
+# GDB to make sure that we havn't loaded the full symbols yet when
+# we test the breakpoint insertion.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set test "breakpoint inside included file"
+gdb_test_multiple "break sep-proc.c:25" "$test" {
+    -re "Breakpoint.*at.* file .*sep-proc.c, line .*" {
+        pass "$test"
+    }
+    -re "No source file named sep-proc.c.*" {
+        fail "$test"
+    }
+}
+
diff --git a/gdb/testsuite/gdb.base/sigaltstack.c b/gdb/testsuite/gdb.base/sigaltstack.c
new file mode 100644 (file)
index 0000000..b7abc9b
--- /dev/null
@@ -0,0 +1,97 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+enum level { MAIN, OUTER, INNER, LEAF, NR_LEVELS };
+
+/* Levels completed flag.  */
+volatile enum level level = NR_LEVELS;
+
+void catcher (int signal);
+
+void
+thrower (enum level next_level, int sig, int itimer, int on_stack)
+{
+  level = next_level;
+  /* Set up the signal handler.  */
+  {
+    struct sigaction act;
+    memset (&act, 0, sizeof (act));
+    act.sa_handler = catcher;
+    act.sa_flags |= on_stack;
+    sigaction (sig, &act, NULL);
+  }
+  /* Set up a one-off timer.  A timer, rather than SIGSEGV, is used as
+     after a timer handler finishes the interrupted code can safely
+     resume.  */
+  {
+    struct itimerval itime;
+    memset (&itime, 0, sizeof (itime));
+    itime.it_value.tv_usec = 250 * 1000;
+    setitimer (itimer, &itime, NULL);
+  }
+  /* Wait.  */
+  while (level != LEAF);
+}
+
+void
+catcher (int signal)
+{
+  /* Find the next level.  */
+  switch (level)
+    {
+    case MAIN:
+      thrower (OUTER, SIGALRM, ITIMER_REAL, SA_ONSTACK);
+      break;
+    case OUTER:
+      thrower (INNER, SIGVTALRM, ITIMER_VIRTUAL, SA_ONSTACK);
+      break;
+    case INNER:
+      level = LEAF;
+      return;
+    }
+}
+
+
+main ()
+{
+  /* Set up the altstack.  */
+  {
+    static char stack[SIGSTKSZ * NR_LEVELS];
+    struct sigaltstack alt;
+    memset (&alt, 0, sizeof (alt));
+    alt.ss_sp = stack;
+    alt.ss_size = SIGSTKSZ;
+    alt.ss_flags = 0;
+    if (sigaltstack (&alt, NULL) < 0)
+      {
+       perror ("sigaltstack");
+       exit (0);
+      }
+  }
+  level = MAIN;
+  catcher (0);
+}
diff --git a/gdb/testsuite/gdb.base/sigaltstack.exp b/gdb/testsuite/gdb.base/sigaltstack.exp
new file mode 100644 (file)
index 0000000..d1e37d8
--- /dev/null
@@ -0,0 +1,105 @@
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+
+# The program sigaltstack.c creates a backtrace containing nested
+# signal handlers on an alternative stack.  This in turn leads to a
+# non-contiguous (and possibly non-monotonic) backtrace - stack
+# address jump at the normal-alt stack boundary.
+
+# This test confirms that GDB can both backtrace through and finish
+# such a stack.
+
+if [target_info exists gdb,nosignals] {
+    verbose "Skipping signals.exp because of nosignals."
+    continue
+}
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile sigaltstack
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${module}.c"
+    return -1
+}
+
+# get things started
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Pass all the alarms straight through (but verbosely)
+gdb_test "handle SIGALRM print pass nostop"
+gdb_test "handle SIGVTALRM print pass nostop"
+gdb_test "handle SIGPROF print pass nostop"
+
+# Advance to main
+if { ![runto_main] } then {
+    gdb_suppress_tests;
+}
+
+# Stop in handle, when at the inner most level
+gdb_test "break catcher if level == INNER"
+gdb_test "continue" ".* catcher .*" "continue to catch"
+# step off the assignment
+gdb_test "next"
+
+# Full backtrace?
+send_gdb "bt\n"
+gdb_expect_list "backtrace" ".*$gdb_prompt $" {
+    "\[\r\n\]+.0 \[^\r\n\]* catcher "
+    "\[\r\n\]+.1  .signal handler called."
+    "\[\r\n\]+.2 \[^\r\n\]* thrower .next_level=INNER"
+    "\[\r\n\]+.3 \[^\r\n\]* catcher "
+    "\[\r\n\]+.4  .signal handler called."
+    "\[\r\n\]+.5 \[^\r\n\]* thrower .next_level=OUTER"
+    "\[\r\n\]+.6 \[^\r\n\]* catcher "
+    "\[\r\n\]+.7 \[^\r\n\]* main .*"
+}
+
+proc finish_test { pattern msg } {
+    global gdb_prompt
+
+    gdb_test_multiple "finish" $msg {
+       -re "Cannot insert breakpoint 0.*${gdb_prompt} $" {
+           # Some platforms use a special read-only page for signal
+           # trampolines.  We can't set a breakpoint there, and we
+           # don't gracefully fall back to single-stepping.
+           setup_kfail "i?86-*-linux*" gdb/1736
+           fail "$msg (could not set breakpoint)"
+       }
+       -re "$pattern.*${gdb_prompt} $" {
+           pass $msg
+       }
+    }
+}
+
+# Finish?
+finish_test "signal handler called." "finish from catch LEAF"
+finish_test "thrower .next_level=INNER, .*" "finish to throw INNER"
+finish_test "catcher .*" "finish to catch INNER"
+finish_test "signal handler called.*" "finish from catch INNER"
+finish_test "thrower .next_level=OUTER, .*" "finish to OUTER"
+finish_test "catcher .*" "finish to catch MAIN"
+finish_test "main .*" "finish to MAIN"
diff --git a/gdb/testsuite/gdb.base/sigbpt.c b/gdb/testsuite/gdb.base/sigbpt.c
new file mode 100644 (file)
index 0000000..b189f6d
--- /dev/null
@@ -0,0 +1,53 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.  */
+
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern void
+keeper (int sig)
+{
+}
+
+volatile long v1 = 0;
+volatile long v2 = 0;
+volatile long v3 = 0;
+
+extern long
+bowler (void)
+{
+  /* Try to read address zero.  Do it in a slightly convoluted way so
+     that more than one instruction is used.  */
+  return *(char *) (v1 + v2 + v3);
+}
+
+int
+main ()
+{
+  static volatile int i;
+
+  struct sigaction act;
+  memset (&act, 0, sizeof act);
+  act.sa_handler = keeper;
+  sigaction (SIGSEGV, &act, NULL);
+
+  bowler ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/sigbpt.exp b/gdb/testsuite/gdb.base/sigbpt.exp
new file mode 100644 (file)
index 0000000..61625b5
--- /dev/null
@@ -0,0 +1,266 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Check that GDB can and only executes single instructions when
+# stepping through a sequence of breakpoints interleaved by a signal
+# handler.
+
+# This test is known to tickle the following problems: kernel letting
+# the inferior execute both the system call, and the instruction
+# following, when single-stepping a system call; kernel failing to
+# propogate the single-step state when single-stepping the sigreturn
+# system call, instead resuming the inferior at full speed; GDB
+# doesn't know how to software single-step across a sigreturn
+# instruction.  Since the kernel problems can be "fixed" using
+# software single-step this is KFAILed rather than XFAILed.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "sigbpt"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+# If we can examine what's at memory address 0, it is possible that we
+# could also execute it.  This could probably make us run away,
+# executing random code, which could have all sorts of ill effects,
+# especially on targets without an MMU.  Don't run the tests in that
+# case.
+
+send_gdb "x 0\n"
+gdb_expect {
+    -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { }
+    -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { }
+    -re ".*$gdb_prompt $" {
+       untested "Memory at address 0 is possibly executable"
+       return
+    }
+}
+
+gdb_test "break keeper"
+
+# Run to bowler, and then single step until there's a SIGSEGV.  Record
+# the address of each single-step instruction (up to and including the
+# instruction that causes the SIGSEGV) in bowler_addrs, and the address
+# of the actual SIGSEGV in segv_addr.
+
+set bowler_addrs bowler
+gdb_test {display/i $pc}
+gdb_test "advance *bowler" "bowler.*" "advance to the bowler"
+set test "stepping to SIGSEGV"
+gdb_test_multiple "stepi" "$test" {
+    -re "Program received signal SIGSEGV.*pc *(0x\[0-9a-f\]*).*$gdb_prompt $" {
+       set segv_addr $expect_out(1,string)
+       pass "$test"
+    }
+    -re " .*pc *(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+       set bowler_addrs [concat $expect_out(1,string) $bowler_addrs]
+       send_gdb "stepi\n"
+       exp_continue
+    }
+}
+
+# Now record the address of the instruction following the faulting
+# instruction in bowler_addrs.
+
+set test "get insn after fault"
+gdb_test_multiple {x/2i $pc} "$test" {
+    -re "(0x\[0-9a-f\]*).*bowler.*(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" {
+       set bowler_addrs [concat $expect_out(2,string) $bowler_addrs]
+       pass "$test"
+    }
+}
+
+# Procedures for returning the address of the instruction before, at
+# and after, the faulting instruction.
+
+proc before_segv { } {
+    global bowler_addrs
+    return [lindex $bowler_addrs 2]
+}
+
+proc at_segv { } {
+    global bowler_addrs
+    return [lindex $bowler_addrs 1]
+}
+
+proc after_segv { } {
+    global bowler_addrs
+    return [lindex $bowler_addrs 0]
+}
+
+# Check that the address table and SIGSEGV correspond.
+
+set test "Verify that SIGSEGV occurs at the last STEPI insn"
+if {[string compare $segv_addr [at_segv]] == 0} {
+    pass "$test"
+} else {
+    fail "$test ($segv_addr [at_segv])"
+}
+
+# Check that the inferior is correctly single stepped all the way back
+# to a faulting instruction.
+
+proc stepi_out { name args } {
+    global gdb_prompt
+
+    # Set SIGSEGV to pass+nostop and then run the inferior all the way
+    # through to the signal handler.  With the handler is reached,
+    # disable SIGSEGV, ensuring that further signals stop the
+    # inferior.  Stops a SIGSEGV infinite loop when a broke system
+    # keeps re-executing the faulting instruction.
+    rerun_to_main
+    gdb_test "handle SIGSEGV nostop print pass" "" "${name}; pass SIGSEGV"
+    gdb_test "continue" "keeper.*" "${name}; continue to keeper"
+    gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV"
+
+    # Insert all the breakpoints.  To avoid the need to step over
+    # these instructions, this is delayed until after the keeper has
+    # been reached.
+    for {set i 0} {$i < [llength $args]} {incr i} {
+       gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+           "${name}; set breakpoint $i of [llength $args]"
+    }
+
+    # Single step our way out of the keeper, through the signal
+    # trampoline, and back to the instruction that faulted.
+    set test "${name}; stepi out of handler"
+    gdb_test_multiple "stepi" "$test" {
+       -re "keeper.*$gdb_prompt $" {
+           send_gdb "stepi\n"
+           exp_continue
+       }
+       -re "signal handler.*$gdb_prompt $" {
+           send_gdb "stepi\n"
+           exp_continue
+       }
+       -re "Program received signal SIGSEGV.*$gdb_prompt $" {
+           kfail gdb/1702 "$test (executed fault insn)"
+       }
+       -re "Breakpoint.*pc *[at_segv] .*bowler.*$gdb_prompt $" {
+           pass "$test (at breakpoint)"
+       }
+       -re "Breakpoint.*pc *[after_segv] .*bowler.*$gdb_prompt $" {
+           kfail gdb/1702 "$test (executed breakpoint)"
+       }
+       -re "pc *[at_segv] .*bowler.*$gdb_prompt $" {
+           pass "$test"
+       }
+       -re "pc *[after_segv] .*bowler.*$gdb_prompt $" {
+           kfail gdb/1702 "$test (skipped fault insn)"
+       }
+       -re "pc *0x\[a-z0-9\]* .*bowler.*$gdb_prompt $" {
+           kfail gdb/1702 "$test (corrupt pc)"
+       }
+    }
+
+    # Clear any breakpoints
+    for {set i 0} {$i < [llength $args]} {incr i} {
+       gdb_test "clear [lindex $args $i]" "Deleted .*" \
+           "${name}; clear breakpoint $i of [llength $args]"
+    }
+}
+
+# Let a signal handler exit, returning to a breakpoint instruction
+# inserted at the original fault instruction.  Check that the
+# breakpoint is hit, and that single stepping off that breakpoint
+# executes the underlying fault instruction causing a SIGSEGV.
+
+proc cont_out { name args } {
+    global gdb_prompt
+
+    # Set SIGSEGV to pass+nostop and then run the inferior all the way
+    # through to the signal handler.  With the handler is reached,
+    # disable SIGSEGV, ensuring that further signals stop the
+    # inferior.  Stops a SIGSEGV infinite loop when a broke system
+    # keeps re-executing the faulting instruction.
+    rerun_to_main
+    gdb_test "handle SIGSEGV nostop print pass" "" "${name}; pass SIGSEGV"
+    gdb_test "continue" "keeper.*" "${name}; continue to keeper"
+    gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV"
+
+    # Insert all the breakpoints.  To avoid the need to step over
+    # these instructions, this is delayed until after the keeper has
+    # been reached.  Always set a breakpoint at the signal trampoline
+    # instruction.
+    set args [concat $args "*[at_segv]"]
+    for {set i 0} {$i < [llength $args]} {incr i} {
+       gdb_test "break [lindex $args $i]" "Breakpoint.*" \
+           "${name}; set breakpoint $i  of [llength $args]"
+    }
+
+    # Let the handler return, it should "appear to hit" the breakpoint
+    # inserted at the faulting instruction.  Note that the breakpoint
+    # instruction wasn't executed, rather the inferior was SIGTRAPed
+    # with the PC at the breakpoint.
+    gdb_test "continue" "Breakpoint.*pc *[at_segv] .*" \
+       "${name}; continue to breakpoint at fault"
+
+    # Now single step the faulted instrction at that breakpoint.
+    gdb_test "stepi" \
+       "Program received signal SIGSEGV.*pc *[at_segv] .*" \
+       "${name}; stepi fault"    
+
+    # Clear any breakpoints
+    for {set i 0} {$i < [llength $args]} {incr i} {
+       gdb_test "clear [lindex $args $i]" "Deleted .*" \
+           "${name}; clear breakpoint $i of [llength $args]"
+    }
+
+}
+
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address.  In all cases the inferior
+# should single-step out of the signal trampoline halting (but not
+# executing) the fault instruction.
+
+stepi_out "stepi"
+stepi_out "stepi bp before segv" "*[before_segv]"
+stepi_out "stepi bp at segv" "*[at_segv]"
+stepi_out "stepi bp before and at segv" "*[at_segv]" "*[before_segv]"
+
+
+# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering
+# breakpoints around the faulting address.  In all cases the inferior
+# should exit the signal trampoline halting at the breakpoint that
+# replaced the fault instruction.
+cont_out "cont"
+cont_out "cont bp after segv" "*[before_segv]"
+cont_out "cont bp before and after segv" "*[before_segv]" "*[after_segv]"
diff --git a/gdb/testsuite/gdb.base/siginfo.c b/gdb/testsuite/gdb.base/siginfo.c
new file mode 100644 (file)
index 0000000..6303f07
--- /dev/null
@@ -0,0 +1,69 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/time.h>
+
+static volatile int done;
+
+#ifdef SA_SIGINFO
+static void /* HANDLER */
+handler (int sig, siginfo_t *info, void *context)
+{
+  done = 1;
+} /* handler */
+#else
+static void
+handler (int sig)
+{
+  done = 1;
+} /* handler */
+#endif
+
+main ()
+{
+  /* Set up the signal handler.  */
+  {
+    struct sigaction action;
+    memset (&action, 0, sizeof (action));
+#ifdef SA_SIGINFO
+    action.sa_sigaction = handler;
+    action.sa_flags |= SA_SIGINFO;
+#else
+    action.sa_handler = handler;
+#endif
+    sigaction (SIGVTALRM, &action, NULL);
+  }
+
+  /* Set up a one-off timer.  A timer, rather than SIGSEGV, is used as
+     after a timer handler finishes the interrupted code can safely
+     resume.  */
+  {
+    struct itimerval itime;
+    memset (&itime, 0, sizeof (itime));
+    itime.it_value.tv_usec = 250 * 1000;
+    setitimer (ITIMER_VIRTUAL, &itime, NULL);
+  }
+  /* Wait.  */
+  while (!done);
+  return 0;
+} /* main */
diff --git a/gdb/testsuite/gdb.base/siginfo.exp b/gdb/testsuite/gdb.base/siginfo.exp
new file mode 100644 (file)
index 0000000..a081ab8
--- /dev/null
@@ -0,0 +1,98 @@
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+
+# The program siginfo.c creates a backtrace containing a signal
+# handler registered using sigaction's sa_sigaction / SA_SIGINFO.
+# Some OS's (e.g., GNU/Linux) use different signal trampolines for
+# sa_sigaction and sa_handler.
+
+# This test first confirms that GDB can backtrace through the
+# alternative sa_sigaction signal handler, and second that GDB can
+# nexti/stepi out of such a handler.
+
+if [target_info exists gdb,nosignals] {
+    verbose "Skipping signals.exp because of nosignals."
+    continue
+}
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile siginfo
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${module}.c"
+    return -1
+}
+
+# get things started
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "display/i \$pc"
+
+# Advance to main
+if { ![runto_main] } then {
+    gdb_suppress_tests;
+}
+
+# Pass all the alarms straight through (but verbosely)
+# gdb_test "handle SIGALRM print pass nostop"
+# gdb_test "handle SIGVTALRM print pass nostop"
+# gdb_test "handle SIGPROF print pass nostop"
+
+# Run to the signal handler, validate the backtrace.
+gdb_test "break handler"
+gdb_test "continue" ".* handler .*" "continue to stepi handler"
+send_gdb "bt\n"
+gdb_expect_list "backtrace for nexti" ".*$gdb_prompt $" {
+    "\[\r\n\]+.0 \[^\r\n\]* handler "
+    "\[\r\n\]+.1  .signal handler called."
+    "\[\r\n\]+.2 \[^\r\n\]* main .*"
+}
+
+# Check that GDB can step the inferior back to main
+set test "step out of handler"
+gdb_test_multiple "step" "${test}" {
+    -re "done = 1;.*${gdb_prompt} $" {
+       send_gdb "$i\n"
+       exp_continue
+    }
+    -re "\} .. handler .*${gdb_prompt} $" {
+       send_gdb "step\n"
+       exp_continue
+    }
+    -re "Program exited normally.*${gdb_prompt} $" {
+       kfail gdb/1613 "$test (program exited)"
+    }
+    -re "(while ..done|return 0).*${gdb_prompt} $" {
+       # After stepping out of a function /r signal-handler, GDB will
+       # advance the inferior until it is at the first instruction of
+       # a code-line.  While typically things return to the middle of
+       # the "while..." (and hence GDB advances the inferior to the
+       # "return..." line) it is also possible for the return to land
+       # on the first instruction of "while...".  Accept both cases.
+       pass "$test"
+    }
+}
diff --git a/gdb/testsuite/gdb.base/signull.c b/gdb/testsuite/gdb.base/signull.c
new file mode 100644 (file)
index 0000000..4139d14
--- /dev/null
@@ -0,0 +1,88 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 1996, 1999, 2003, 2004 Free Software Foundation, Inc.
+
+   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.  */
+
+#include <signal.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+enum tests {
+  code_entry_point, code_descriptor, data_read, data_write
+};
+
+static volatile enum tests test;
+
+/* Some basic types and zero buffers.  */
+
+typedef long data_t;
+typedef long code_t (void);
+data_t *volatile data;
+code_t *volatile code;
+/* "desc" is intentionally initialized to a data object.  This is
+   needed to test function descriptors on arches like ia64.  */
+data_t zero[10];
+code_t *volatile desc = (code_t *) (void *) zero;
+
+sigjmp_buf env;
+
+extern void
+keeper (int sig)
+{
+  siglongjmp (env, 0);
+}
+
+extern long
+bowler (void)
+{
+  switch (test)
+    {
+    case data_read:
+      /* Try to read address zero.  */
+      return (*data);
+    case data_write:
+      /* Try to write (the assignment) to address zero.  */
+      return (*data) = 1;
+    case code_entry_point:
+      /* For typical architectures, call a function at address
+        zero.  */
+      return (*code) ();
+    case code_descriptor:
+      /* For atypical architectures that use function descriptors,
+        call a function descriptor, the code field of which is zero
+        (which has the effect of jumping to address zero).  */
+      return (*desc) ();
+    }
+}
+
+int
+main ()
+{
+  static volatile int i;
+
+  struct sigaction act;
+  memset (&act, 0, sizeof act);
+  act.sa_handler = keeper;
+  sigaction (SIGSEGV, &act, NULL);
+
+  for (i = 0; i < 10; i++)
+    {
+      sigsetjmp (env, 1);
+      bowler ();
+    }
+}
diff --git a/gdb/testsuite/gdb.base/signull.exp b/gdb/testsuite/gdb.base/signull.exp
new file mode 100644 (file)
index 0000000..59b1a56
--- /dev/null
@@ -0,0 +1,122 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Check that GDB can trigger and backtrace SIGSEGV signal stacks
+# caused by both accessing (data) and executing (code) at address
+# zero.
+
+# On function descriptor architectures, a zero descriptor, instead of
+# a NULL pointer, is used.  That way the NULL code test always
+# contains a zero code reference.
+
+# For recovery, sigjmp/longjmp are used.
+
+# This also tests backtrace/gdb1476.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "signull"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+# If we can examine what's at memory address 0, it is possible that we
+# could also execute it.  This could probably make us run away,
+# executing random code, which could have all sorts of ill effects,
+# especially on targets without an MMU.  Don't run the tests in that
+# case.
+
+send_gdb "x 0\n"
+gdb_expect {
+    -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { }
+    -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { }
+    -re ".*$gdb_prompt $" {
+       untested "Memory at address 0 is possibly executable"
+       return
+    }
+}
+
+# If an attempt to call a NULL pointer leaves the inferior in main,
+# then function pointers are descriptors, probe this and remember the
+# result.
+
+gdb_test "set test = code_entry_point" "" "set for function pointer probe"
+set test "probe function pointer"
+set function_pointer code_entry_point
+gdb_test_multiple "continue" "$test" {
+    -re "Program received signal SIGSEGV.*bowler .*$gdb_prompt $" {
+       set function_pointer code_descriptor
+       pass "$test (function descriptor)"
+    }
+    -re "Program received signal SIGSEGV.*0.*$gdb_prompt $" {
+       pass "$test (function entry-point)"
+    }
+}
+
+# Re-start from scratch, breakpoint the bowler so that control is
+# regained after each test, and run up to that.
+rerun_to_main
+gdb_test "break bowler"
+gdb_test "break keeper"
+# By default Stop:Yes Print:Yes Pass:Yes
+gdb_test "handle SIGSEGV" "SIGSEGV.*Yes.*Yes.*Yes.*Segmentation fault"
+
+# For the given signal type, check that: the SIGSEGV occures; a
+# backtrace from the SEGV works; the sigsegv is delivered; a backtrace
+# through the SEGV works.
+
+proc test_segv { name tag bt_from_segv bt_from_keeper } {
+    gdb_test continue "Breakpoint.* bowler.*" "${name}; start with the bowler"
+    # NB: Don't use $tag in the testname - changes across systems.
+    gdb_test "set test = $tag" "" "${name}; select the pointer type"
+    gdb_test continue "Program received signal SIGSEGV.*" \
+       "${name}; take the SIGSEGV"
+    gdb_test backtrace $bt_from_segv "${name}; backtrace from SIGSEGV"
+    gdb_test continue "Breakpoint.* keeper.*" "${name}; continue to the keeper"
+    gdb_test backtrace $bt_from_keeper "${name}; backtrace from keeper through SIGSEGV"
+}
+
+test_segv "data read" data_read \
+    {#0 .* bowler .*#1  .* main .*} \
+    {#0 .* keeper .*#1  .* handler .*#2 .* bowler .*#3  .* main .*}
+test_segv "data write" data_write \
+    {#0 .* bowler .*#1  .* main .*} \
+    {#0 .* keeper .*#1  .* handler .*#2 .* bowler .*#3  .* main .*}
+test_segv code $function_pointer \
+    {#0 .* 0x0+ .*#1 .* bowler .*#2  .* main .*} \
+    {#0 .* keeper .*#1  .* handler .*#2 .* 0x0+ .*#3 .* bowler .*#4 .* main .*}
diff --git a/gdb/testsuite/gdb.base/sigstep.c b/gdb/testsuite/gdb.base/sigstep.c
new file mode 100644 (file)
index 0000000..0f0d8b7
--- /dev/null
@@ -0,0 +1,68 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/time.h>
+
+static volatile int done;
+
+static void
+handler (int sig)
+{
+  done = 1;
+} /* handler */
+
+struct itimerval itime;
+struct sigaction action;
+
+/* The enum is so that GDB can easily see these macro values.  */
+enum {
+  itimer_real = ITIMER_REAL,
+  itimer_virtual = ITIMER_VIRTUAL
+} itimer = ITIMER_VIRTUAL;
+
+main ()
+{
+
+  /* Set up the signal handler.  */
+  memset (&action, 0, sizeof (action));
+  action.sa_handler = handler;
+  sigaction (SIGVTALRM, &action, NULL);
+  sigaction (SIGALRM, &action, NULL);
+
+  /* The values needed for the itimer.  This needs to be at least long
+     enough for the setitimer() call to return.  */
+  memset (&itime, 0, sizeof (itime));
+  itime.it_value.tv_usec = 250 * 1000;
+
+  /* Loop for ever, constantly taking an interrupt.  */
+  while (1)
+    {
+      /* Set up a one-off timer.  A timer, rather than SIGSEGV, is
+        used as after a timer handler finishes the interrupted code
+        can safely resume.  */
+      setitimer (itimer, &itime, NULL);
+      /* Wait.  */
+      while (!done);
+      done = 0;
+    }
+}
diff --git a/gdb/testsuite/gdb.base/sigstep.exp b/gdb/testsuite/gdb.base/sigstep.exp
new file mode 100644 (file)
index 0000000..55de445
--- /dev/null
@@ -0,0 +1,423 @@
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+
+# The program sigstep.c creates a very simple backtrace containing one
+# signal handler and signal trampoline.  A flag is set and then the
+# handler returns.  This is repeated at infinitum.
+
+# This test runs the program up to the signal handler, and then
+# attempts to step/next out of the handler and back into main.
+
+if [target_info exists gdb,nosignals] {
+    verbose "Skipping sigstep.exp because of nosignals."
+    continue
+}
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile sigstep
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile ${module}.c"
+    return -1
+}
+
+# get things started
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "display/i \$pc"
+
+# Advance to main
+if { ![runto_main] } then {
+    gdb_suppress_tests;
+}
+
+# Pass all the alarms straight through (but verbosely)
+# gdb_test "handle SIGALRM print pass nostop"
+# gdb_test "handle SIGVTALRM print pass nostop"
+# gdb_test "handle SIGPROF print pass nostop"
+
+# Run to the signal handler, validate the backtrace.
+gdb_test "break handler"
+gdb_test "continue" ".* handler .*" "continue to stepi handler"
+send_gdb "bt\n"
+gdb_expect_list "backtrace for nexti" ".*$gdb_prompt $" {
+    "\[\r\n\]+.0 \[^\r\n\]* handler "
+    "\[\r\n\]+.1  .signal handler called."
+    "\[\r\n\]+.2 \[^\r\n\]* main .*"
+}
+
+proc advance { i } {
+    global gdb_prompt
+    set prefix "$i from handler"
+
+    # Get us back into the handler
+    gdb_test "continue" ".* handler .*" "$prefix; continue to handler"
+
+    set test "$prefix; leave handler"
+    gdb_test_multiple "$i" "${test}" {
+       -re "done = 1;.*${gdb_prompt} $" {
+           send_gdb "$i\n"
+           exp_continue -continue_timer
+       }
+       -re "\} .. handler .*${gdb_prompt} $" {
+           send_gdb "$i\n"
+           exp_continue -continue_timer
+       }
+       -re "Program exited normally.*${gdb_prompt} $" {
+           setup_kfail powerpc-*-*bsd* gdb/1639
+           fail "$test (program exited)"
+       }
+       -re "(while ..done|done = 0).*${gdb_prompt} $" {
+           # After stepping out of a function /r signal-handler, GDB will
+           # advance the inferior until it is at the first instruction of
+           # a code-line.  While typically things return to the middle of
+           # the "while..." (and hence GDB advances the inferior to the
+           # "return..." line) it is also possible for the return to land
+           # on the first instruction of "while...".  Accept both cases.
+           pass "$test"
+       }
+    }
+}
+
+proc advancei { i } {
+    global gdb_prompt
+    set prefix "$i from handleri"
+    set program_exited 0
+
+    # Get us back into the handler
+    gdb_test "continue" ".* handler .*" "$prefix; continue to handler"
+
+    set test "$prefix; leave handler"
+    gdb_test_multiple "$i" "${test}" {
+        -re "Cannot insert breakpoint 0.*${gdb_prompt} $" {
+            # Some platforms use a special read-only page for signal
+            # trampolines.  We can't set a breakpoint there, and we
+            # don't gracefully fall back to single-stepping.
+            setup_kfail "i?86-*-linux*" gdb/1736
+            fail "$test (could not set breakpoint)"
+           return
+        }
+       -re "done = 1;.*${gdb_prompt} $" {
+           send_gdb "$i\n"
+           exp_continue -continue_timer
+       }
+       -re "\} .. handler .*${gdb_prompt} $" {
+           send_gdb "$i\n"
+           exp_continue -continue_timer
+       }
+       -re "signal handler called.*${gdb_prompt} $" {
+           pass "$test"
+       }
+       -re "main .*${gdb_prompt} $" {
+           fail "$test (in main)"
+       }
+       -re "Program exited normally.*${gdb_prompt} $" {
+           fail "$test (program exited)"
+           set program_exited 1
+       }
+       -re "Make handler return now.*y or n. $" {
+           send_gdb "y\n"
+           exp_continue -continue_timer
+       }
+    }
+
+    set test "$prefix; leave signal trampoline"
+    gdb_test_multiple "$i" "${test}" {
+       -re "while .*${gdb_prompt} $" {
+           pass "$test (in main)"
+       }
+       -re "signal handler called.*${gdb_prompt} $" {
+           send_gdb "$i\n"
+           exp_continue -continue_timer
+       }
+       -re "return .*${gdb_prompt} $" {
+           fail "$test (stepped)"
+       }
+       -re "Make .*frame return now.*y or n. $" {
+           send_gdb "y\n"
+           exp_continue -continue_timer
+       }
+       -re "Program exited normally.*${gdb_prompt} $" {
+           kfail gdb/1639 "$test (program exited)"
+           set program_exited 1
+       }
+       -re "The program is not being run.*${gdb_prompt} $" {
+           if { $program_exited } {
+               # Previously kfailed with an exit
+               pass "$test (the program is not being run)"
+           } else {
+               fail "$test (the program is not being run)"
+           }
+       }
+    }
+}
+
+# Check that we can step/next our way out of a signal handler.
+
+advance step
+advancei stepi
+
+advance next
+advancei nexti
+
+advancei finish
+advancei return
+gdb_test "set done = 1" "" "Set done as return will have skipped it"
+
+
+# Check that we can step/next our way into / over a signal handler.
+
+# There are at least the following cases: breakpoint @pc VS breakpoint
+# in handler VS step / next / continue.
+
+# Use the real-time itimer, as otherwize the process never gets enough
+# time to expire the timer.
+
+delete_breakpoints
+set infinite_loop [gdb_get_line_number {while (!done)}]
+gdb_test "set itimer = itimer_real"
+gdb_test "break [gdb_get_line_number {done = 0}]"
+
+# Try stepping when there's a signal pending, and a breakpoint at the
+# handler.  Should step into the signal handler.
+
+proc skip_to_handler { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i to handler"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+       -re "done = 0.*$gdb_prompt " {
+           pass "$test"
+       }
+       # other patterns can go here
+    }
+    
+    # Advance to the infinite loop
+    gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    # Insert / remove the handler breakpoint.
+    gdb_test "break handler" "" "$prefix; break handler"
+    gdb_test "$i" " handler .*" "$prefix; performing $i"
+    gdb_test "clear handler" "" "$prefix; clear handler"
+}
+
+skip_to_handler step
+skip_to_handler next
+skip_to_handler continue
+
+# Try stepping when there's a signal pending, and a breakpoint at the
+# handler's entry-point.  Should step into the signal handler stopping
+# at the entry-point.
+
+# Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a
+# signal, resume the process at the first instruction of the signal
+# handler and not the first instruction of the signal trampoline.  The
+# stack is constructed such that the signal handler still appears to
+# have been called by the trampoline code.  This test checks that it
+# is possible to stop the inferior, even at that first instruction.
+
+proc skip_to_handler_entry { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i to handler entry"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+       -re "done = 0.*$gdb_prompt " {
+           pass "$test"
+       }
+       # other patterns can go here
+    }
+    
+    # Advance to the infinite loop
+    gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    # Insert / remove the handler breakpoint.
+    gdb_test "break *handler" "" "$prefix; break handler"
+    gdb_test "$i" " handler .*" "$prefix; performing $i"
+    gdb_test "clear *handler" "" "$prefix; clear handler"
+}
+
+skip_to_handler_entry step
+skip_to_handler_entry next
+skip_to_handler_entry continue
+
+# Try stepping when there's a signal pending but no breakpoints.
+# Should skip the handler advancing to the next line.
+
+proc skip_over_handler { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i over handler"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+       -re "done = 0.*$gdb_prompt " {
+           pass "$test"
+       }
+       # other patterns can go here
+    }
+    
+    # Advance to the infinite loop
+    gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    gdb_test "$i" "done = 0.*" "$prefix; performing $i"
+}
+
+skip_over_handler step
+skip_over_handler next
+skip_over_handler continue
+
+# Try stepping when there's a signal pending, a pre-existing
+# breakpoint at the current instruction, and a breakpoint in the
+# handler.  Should advance to the signal handler.
+
+proc breakpoint_to_handler { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i on breakpoint, to handler"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+       -re "done = 0.*$gdb_prompt " {
+           pass "$test"
+       }
+       # other patterns can go here
+    }
+    
+    gdb_test "break $infinite_loop" "" "$prefix; break infinite loop"
+    gdb_test "break handler" "" "$prefix; break handler"
+
+    # Continue to the infinite loop
+    gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    setup_kfail "i*86-*-*" gdb/1738
+    gdb_test "$i" " handler .*" "$prefix; performing $i"
+    gdb_test "clear $infinite_loop" "" "$prefix; clear infinite loop"
+    gdb_test "clear handler" "" "$prefix; clear handler"
+}
+
+breakpoint_to_handler step
+breakpoint_to_handler next
+breakpoint_to_handler continue
+
+# Try stepping when there's a signal pending, and a breakpoint at the
+# handler's entry instruction and a breakpoint at the current
+# instruction.  Should step into the signal handler and breakpoint at
+# that entry instruction.
+
+# Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a
+# signal, resume the process at the first instruction of the signal
+# handler and not the first instruction of the signal trampoline.  The
+# stack is constructed such that the signal handler still appears to
+# have been called by the trampoline code.  This test checks that it
+# is possible to stop the inferior, even at that first instruction.
+
+proc breakpoint_to_handler_entry { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i on breakpoint, to handler entry"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+       -re "done = 0.*$gdb_prompt " {
+           pass "$test"
+       }
+       # other patterns can go here
+    }
+    
+    gdb_test "break $infinite_loop" "" "$prefix; break infinite loop"
+    gdb_test "break *handler" "" "$prefix; break handler"
+
+    # Continue to the infinite loop
+    gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    setup_kfail "i*86-*-*" gdb/1738
+    gdb_test "$i" " handler .*" "$prefix; performing $i"
+    gdb_test "clear $infinite_loop" "" "$prefix; clear infinite loop"
+    gdb_test "clear *handler" "" "$prefix; clear handler"
+}
+
+breakpoint_to_handler_entry step
+breakpoint_to_handler_entry next
+breakpoint_to_handler_entry continue
+
+# Try stepping when there's a signal pending, and a pre-existing
+# breakpoint at the current instruction, and no breakpoint in the
+# handler.  Should advance to the next line.
+
+proc breakpoint_over_handler { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i on breakpoint, skip handler"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+       -re "done = 0.*$gdb_prompt " {
+           pass "$test"
+       }
+       # other patterns can go here
+    }
+    
+    gdb_test "break $infinite_loop" "" "$prefix; break infinite loop"
+
+    # Continue to the infinite loop
+    gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    gdb_test "$i" "done = 0.*" "$prefix; performing $i"
+    gdb_test "clear $infinite_loop" "" "$prefix; clear infinite loop"
+}
+
+breakpoint_over_handler step
+breakpoint_over_handler next
+breakpoint_over_handler continue
diff --git a/gdb/testsuite/gdb.base/unload.c b/gdb/testsuite/gdb.base/unload.c
new file mode 100644 (file)
index 0000000..5c5e3d3
--- /dev/null
@@ -0,0 +1,58 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+int k = 0;
+
+#define SHLIB_NAME SHLIB_DIR "/unloadshr.sl"
+
+int main()
+{
+  void *handle;
+  int (*unloadshr) (int);
+  int y;
+  const char *msg;
+
+  handle = dlopen (SHLIB_NAME, RTLD_LAZY);
+  msg = dlerror ();
+  
+  if (!handle)
+    {
+      fprintf (stderr, msg);
+      exit (1);
+    }
+
+  unloadshr = (int (*)(int))dlsym (handle, "shrfunc1");
+
+  if (!unloadshr)
+    {
+      fprintf (stderr, dlerror ());
+      exit (1);
+    }
+
+  y = (*unloadshr)(3);
+
+  printf ("y is %d\n", y);
+
+  dlclose (handle);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/unload.exp b/gdb/testsuite/gdb.base/unload.exp
new file mode 100644 (file)
index 0000000..242dcf5
--- /dev/null
@@ -0,0 +1,144 @@
+#   Copyright 2003, 2004
+#   Free Software Foundation, Inc.
+
+# 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.  
+
+# This file was created by Jeff Johnston. (jjohnstn@redhat.com)
+# The shared library compilation portion was copied from shlib-call.exp which was
+# written by Elena Zannoni (ezannoni@redhat.com).
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+# are we on a target board?
+if ![isnative] then {
+    return 0
+}
+
+set testfile "unload"
+set libfile "unloadshr"
+set libsrcfile ${libfile}.c
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set shlibdir ${objdir}/${subdir}
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+set dl_lib_flag ""
+switch -glob [istarget] {
+    "hppa*-hp-hpux*" { }
+    "*-*-linux*"     { set dl_lib_flag "libs=-ldl" }
+    "*-*-solaris*"   { set dl_lib_flag "libs=-ldl" }
+    default          { }
+}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "additional_flags=-DSHLIB_DIR\=\"${shlibdir}\"" $dl_lib_flag]] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Build the shared libraries this test case needs.
+#
+
+if {$gcc_compiled == 0} {
+    if [istarget "hppa*-hp-hpux*"] then {
+       set additional_flags "additional_flags=+z"
+    } elseif { [istarget "mips-sgi-irix*"] } {
+       # Disable SGI compiler's implicit -Dsgi
+       set additional_flags "additional_flags=-Usgi"
+    } else {
+       # don't know what the compiler is...
+       set additional_flags ""
+    }
+} else {
+    if { ([istarget "powerpc*-*-aix*"]
+       || [istarget "rs6000*-*-aix*"]) } {
+       set additional_flags ""
+    } else {
+       set additional_flags "additional_flags=-fpic"
+    }
+}
+
+if {[gdb_compile "${srcdir}/${subdir}/${libsrcfile}" "${objdir}/${subdir}/${libfile}.o" object [list debug $additional_flags]] != ""} {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [istarget "hppa*-*-hpux*"] {
+    remote_exec build "ld -b ${objdir}/${subdir}/${libfile}.o -o ${objdir}/${subdir}/${libfile}.sl"
+} else {
+    set additional_flags "additional_flags=-shared"
+    if {[gdb_compile "${objdir}/${subdir}/${libfile}.o" "${objdir}/${subdir}/${libfile}.sl" executable [list debug $additional_flags]] != ""} {
+       gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+    }
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if [target_info exists gdb_stub] {
+    gdb_step_for_stub;
+}
+
+#
+# Test setting a breakpoint in a dynamically loaded library which is
+# manually loaded and unloaded
+#
+
+gdb_test_multiple "break shrfunc1" "set pending breakpoint" {
+     -re ".*Make breakpoint pending.*y or \\\[n\\\]. $" {
+           gdb_test "y" "Breakpoint.*shrfunc1.*pending." "set pending breakpoint"
+     }
+}
+
+gdb_test "info break" \
+    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*shrfunc1.*" \
+"single pending breakpoint info"
+
+set unloadshr_line [gdb_get_line_number "unloadshr break" ${srcdir}/${subdir}/${libsrcfile}]
+
+gdb_test "run" \
+"Starting program.*unload.*
+Breakpoint.*at.*
+Pending breakpoint \"shrfunc1\" resolved.*
+Breakpoint.*, shrfunc1 \\\(x=3\\\).*unloadshr.c:$unloadshr_line.*" \
+"running program"
+
+gdb_test "continue" \
+"Continuing.*y is 7.*warning: Temporarily disabling breakpoints for.*unloadshr.sl.*Program exited normally." \
+"continuing to end of program"
+
+#
+# Try to rerun program and verify that shared breakpoint is reset properly
+#
+
+gdb_test "run" \
+".*Breakpoint.*shrfunc1.*at.*unloadshr.c:$unloadshr_line.*" \
+"rerun to shared library breakpoint"
+
+gdb_test "continue" \
+"Continuing.*y is 7.*warning: Temporarily disabling breakpoints for.*unloadshr.sl.*Program exited normally." \
+"continuing to end of program second time"
+
diff --git a/gdb/testsuite/gdb.base/unloadshr.c b/gdb/testsuite/gdb.base/unloadshr.c
new file mode 100644 (file)
index 0000000..3896e67
--- /dev/null
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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. */
+
+#include <stdio.h>
+
+int shrfunc1 (int x)
+{
+  return x + 4; /* unloadshr break */
+}
diff --git a/gdb/testsuite/gdb.fortran/Makefile.in b/gdb/testsuite/gdb.fortran/Makefile.in
new file mode 100644 (file)
index 0000000..a1c3b07
--- /dev/null
@@ -0,0 +1,34 @@
+# Makefile for regression testing the GNU debugger.
+# Copyright 1992, 1993, 1994, 1995, 1996, 1999, 2001, 2003, 2004
+# Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# GDB 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, or (at your option)
+# any later version.
+
+# GDB 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.
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = 
+
+all info install-info dvi install uninstall installcheck check:
+       @echo "Nothing to be done for $@..."
+
+clean mostlyclean:
+       -rm -f *~ *.o *.ci
+       -rm -f core ${EXECUTABLES}
+
+distclean maintainer-clean realclean: clean
+       -rm -f Makefile config.status config.log
diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp
new file mode 100644 (file)
index 0000000..e7d46bd
--- /dev/null
@@ -0,0 +1,523 @@
+# Copyright 1988, 1990, 1991, 1992, 1994, 1997, 1999, 2000, 2002,
+# 2003, 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# This file was written by Rob Savoye. (rob@cygnus.com)
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if [is_remote target] {
+    return
+}
+
+# Not all of the lines of code near the start of main are executed for
+# every machine.  Also, optimization may reorder some of the lines.
+# So all we do is try to step or next over everything until we get
+# to a line that we know is always executed.
+
+proc do_steps_and_nexts {} {
+    global gdb_prompt
+    global srcdir
+    gdb_reinitialize_dir $srcdir/..
+
+    for {set count 0} {$count < 32} {incr count} {
+       send_gdb "list\n"
+       # NOTE: carlton/2002-12-11: The "initial brace" and
+       # "current_directory initialization" possibilities happen to
+       # me with GCC 3.1 on i686-pc-linux-gnu when I compile with
+       # optimization.
+       gdb_expect {
+           -re ".*context = data.*$gdb_prompt $" {
+               set description "step over context initialization"
+               set command "step"
+           }
+           -re ".*argc = context->argc.*$gdb_prompt $" {
+               set description "step over argc initialization"
+               set command "step"
+           }
+           -re ".*argv = context->argv.*$gdb_prompt $" {
+               set description "step over argv initialization"
+               set command "step"
+           }
+           -re ".*quiet = 0.*$gdb_prompt $" {
+               set description "step over quiet initialization"
+               set command "step"
+           }
+           -re ".*batch = 0.*$gdb_prompt $" {
+               set description "step over batch initialization"
+               set command "step"
+           }
+           -re ".*symarg = NULL.*$gdb_prompt $" {
+               set description "step over symarg initialization"
+               set command "step"
+           }
+           -re ".*execarg = NULL.*$gdb_prompt $" {
+               set description "step over execarg initialization"
+               set command "step"
+           }
+           -re ".*corearg = NULL.*$gdb_prompt $" {
+               set description "step over corearg initialization"
+               set command "step"
+           }
+           -re ".*cdarg = NULL.*$gdb_prompt $" {
+               set description "step over cdarg initialization"
+               set command "step"
+           }
+           -re ".*ttyarg = NULL.*$gdb_prompt $" {
+               set description "step over ttyarg initialization"
+               set command "step"
+           }
+           -re ".*time_at_startup = get_run_time.*$gdb_prompt $" {
+               set description "next over get_run_time and everything it calls"
+               set command "next"
+           }
+           -re ".*START_PROGRESS.*$gdb_prompt $" {
+               # Note: ezannoni/2004/02/17: This check should be
+               # removed, since as of today that source line is not
+               # in gdb anymore.
+               set description "next over START_PROGRESS and everything it calls"
+               set command "next"
+           }
+           -re ".*mac_init.*$gdb_prompt $" {
+               set description "next over mac_init and everything it calls"
+               set command "next"
+           }
+           -re ".*init_malloc.*$gdb_prompt $" {
+               # gdb 6.2.X is the last gdb which called init_malloc
+               set description "next over init_malloc and everything it calls"
+               set command "next"
+           }
+           -re ".*lim_at_start.*$gdb_prompt $" {
+               set description "next over lim_at_start initialization"
+               set command "next"
+           }
+           -re ".*count . 0x3.*$gdb_prompt $" {
+               set description "next over conditional stack alignment code 1"
+               set command "next"
+           }
+           -re ".*if .i != 0.*$gdb_prompt $" {
+               set description "next over conditional stack alignment code 2"
+               set command "next"
+           }
+           -re ".*alloca .i - 4.*$gdb_prompt $" {
+               set description "next over conditional stack alignment alloca"
+               set command "next"
+           }
+           -re ".*cmdsize = 1.*$gdb_prompt $" {
+               set description "step over cmdsize initialization"
+               set command "next"
+           }
+           -re ".*cmdarg = .* xmalloc.*$gdb_prompt $" {
+               set description "next over cmdarg initialization via xmalloc"
+               set command "next"
+           }
+           -re ".*ncmd = 0.*$gdb_prompt $" {
+               set description "next over ncmd initialization"
+               set command "next"
+           }
+           -re ".*dirsize = 1.*$gdb_prompt $" {
+               set description "next over dirsize initialization"
+               set command "next"
+           }
+           -re ".*dirarg = .* xmalloc.*$gdb_prompt $" {
+               return
+           }
+           -re ".*setlocale .LC_MESSAGES,.*$gdb_prompt $" {
+               set description "next over setlocale LC_MESSAGES"
+               set command "next"
+           }
+           -re ".*setlocale .LC_CTYPE,.*$gdb_prompt $" {
+               set description "next over setlocale LC_CTYPE"
+               set command "next"
+           }
+           -re ".*bindtextdomain .PACKAGE, LOCALEDIR.;.*$gdb_prompt $" {
+               set description "next over bindtextdomain"
+               set command "next"
+           }
+           -re ".*textdomain .PACKAGE.;.*$gdb_prompt $" {
+               set description "next over textdomain PACKAGE"
+               set command "next"
+           }
+           -re "\[0-9\]*\t\{\r\n$gdb_prompt $" {
+               set description "step over initial brace"
+               set command "step"
+           }
+           -re ".*current_directory = gdb_dirbuf.*$gdb_prompt $" {
+               set description "step over current_directory initialization"
+               set command "step"
+           }
+           -re ".*gdb_sysroot = .*$gdb_prompt $" {
+               # NOTE: carlton/2003-01-15: More optimization reordering,
+               # observed on GCC 3.1.
+               set description "step over gdb_sysroot initialization"
+               set command "step"
+           }
+           -re ".*ndir = 0.*$gdb_prompt $" {
+               set description "step over ndir initialization"
+               set command "step"
+           }
+           -re ".*instream = stdin.*$gdb_prompt $" {
+               set description "step over instream initialization"
+               set command "step"
+           }
+           -re ".*getcwd .gdb_dirbuf, sizeof .gdb_dirbuf..;.*$gdb_prompt $" {
+               set description "next over getcwd"
+               set command "next"
+           }
+           -re "\[ \t\]+\{\r\n$gdb_prompt $" {
+               setup_xfail "mips-*-irix5*"
+               fail "$description ended up at odd location"
+           }
+           -re ".*main.c.*No such file or directory.*$gdb_prompt $" {
+               setup_xfail "rs6000-*-aix3*"
+               fail "must be able to list source lines"
+               return
+           }
+           -re ".*$gdb_prompt $" {
+               fail "unknown source line after $description"
+               return
+           }
+           default {
+               fail "unknown source line near main"
+               return
+           }
+       }
+       send_gdb "$command\n"
+       gdb_expect {
+           -re ".*No such file or directory.\r\n$gdb_prompt $" {
+               fail "$description (no source available)"
+           }
+           -re ".*A file or directory .* does not exist..\r\n$gdb_prompt $" {
+               fail "$description (no source available)"
+           }
+           -re ".*$gdb_prompt $" {
+               pass "$description"
+           }
+           timeout {
+               fail "$description (timeout)"
+           }
+       }
+    }
+}
+
+proc test_with_self { executable } {
+    global gdb_prompt
+    global tool
+    global det_file
+    global decimal
+    global timeout
+
+    # load yourself into the debugger
+    # This can take a relatively long time, particularly for testing where
+    # the executable is being accessed over a network, or where gdb does not
+    # support partial symbols for a particular target and has to load the
+    # entire symbol table.  Set the timeout to 10 minutes, which should be
+    # adequate for most environments (it *has* timed out with 5 min on a
+    # SPARCstation SLC under moderate load, so this isn't unreasonable).
+    # After gdb is started, set the timeout to 30 seconds for the duration
+    # of this test, and then back to the original value.
+
+    set oldtimeout $timeout
+    set timeout 600
+    verbose "Timeout is now $timeout seconds" 2
+
+    global gdb_file_cmd_debug_info
+    set gdb_file_cmd_debug_info "unset"
+
+    set result [gdb_load $executable]
+    set timeout $oldtimeout
+    verbose "Timeout is now $timeout seconds" 2
+
+    if { $result != 0 } then {
+       return -1
+    }
+
+    if { $gdb_file_cmd_debug_info != "debug" } then {
+       untested "No debug information, skipping testcase."
+       return -1
+    }
+
+    # disassemble yourself
+    gdb_test "x/10i main" \
+           "x/10i.*main.*main.$decimal.*main.$decimal.*" \
+           "Disassemble main"
+
+    # Set a breakpoint at main
+    gdb_test "break captured_main" \
+           "Breakpoint.*at.* file.*, line.*" \
+           "breakpoint in captured_main"
+
+    # We'll need this when we send a ^C to GDB.  Need to do it before we
+    # run the program and gdb starts saving and restoring tty states.
+    # On Ultrix, we don't need it and it is really slow (because shell_escape
+    # doesn't use vfork).
+    if ![istarget "*-*-ultrix*"] then {
+       gdb_test "shell stty intr '^C'" "" \
+           "set interrupt character in test_with_self"
+    }
+
+    # FIXME: If we put this after the run to main, the first list
+    # command doesn't print the same line as the current line where
+    # gdb is stopped.
+    gdb_test "set listsize 1" "" "set listsize to 1"
+
+    # run yourself
+    # It may take a very long time for the inferior gdb to start (lynx),
+    # so we bump it back up for the duration of this command.
+    set timeout 600
+
+    set description "run until breakpoint at captured_main"
+    send_gdb "run -nw\n"
+    gdb_expect {
+       -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.* at .*main.c:.*$gdb_prompt $" {
+           pass "$description"
+       }
+       -re "Starting program.*Breakpoint \[0-9\]+,.*captured_main .data.*$gdb_prompt $" {
+           xfail "$description (line numbers scrambled?)"
+       }
+       -re "vfork: No more processes.*$gdb_prompt $" {
+           fail "$description (out of virtual memory)"
+           set timeout $oldtimeout
+           verbose "Timeout is now $timeout seconds" 2
+           return -1
+       }
+       -re ".*$gdb_prompt $" {
+           fail "$description"
+           set timeout $oldtimeout
+           verbose "Timeout is now $timeout seconds" 2
+           return -1
+       }
+       timeout {
+           fail "$description (timeout)"
+       }
+    }
+
+    set timeout $oldtimeout
+    verbose "Timeout is now $timeout seconds" 2
+
+    # do we have a version number ?
+    send_gdb "print version\n"
+    gdb_expect {
+       -re ".\[0-9\]+ = .\[0-9.\]+.*$gdb_prompt $" {
+           pass "printed version as string"
+       }
+       -re ".\[0-9\]+ = +0x.*\[0-9.\]+.*$gdb_prompt $" {
+           pass "printed version as pointer"
+       }
+       -re ".\[0-9\]+ = +.+ +0x.*\[0-9.\]+.*$gdb_prompt $" {
+           pass "printed version with cast"
+       }
+       -re ".*$gdb_prompt $"   { fail "printed version" }
+       timeout         { fail "(timeout) printed version" }
+    }
+
+    do_steps_and_nexts
+
+    gdb_test "print \"foo\"" ".\[0-9\]+ = \"foo\"" "print a string"
+
+    # do_steps_and_nexts left us ready to execute an xmalloc call,
+    # so give that a try.
+    # If we don't actually enter the xmalloc call when we give a
+    # step command that seems like a genuine bug.  It seems to happen
+    # on most RISC processors.
+    # NOTE drow/2003-06-22: However, if we step back to the preceding two
+    # lines, just keep stepping until we enter.
+    set stepped_back 0
+    setup_xfail "alpha-*-*" "mips-*-*"
+    set description "step into xmalloc call"
+    send_gdb "step\n"
+    gdb_expect {
+       -re "ncmd = 0;.*$gdb_prompt $" {
+           set stepped_back 1
+           send_gdb "step\n"
+           exp_continue
+       }
+        -re ".*cmdarg = .* xmalloc.*$gdb_prompt $" {
+           set stepped_back 1
+           send_gdb "step\n"
+           exp_continue
+        }
+       -re "dirsize = 1;.*$gdb_prompt $" {
+           set stepped_back 1
+           send_gdb "step\n"
+           exp_continue
+       }
+       -re ".*dirarg = .* xmalloc.*$gdb_prompt $" {
+           if { $stepped_back == 1 } {
+               send_gdb "step\n"
+               exp_continue
+           } else {
+               fail "$description"
+           }
+       }
+       -re "xmalloc.*size=.*at.*utils.c.*$gdb_prompt $" {
+           pass "$description"
+       }
+       -re ".*No such file or directory.\r\n$gdb_prompt $" {
+           pass "$description (no source available)"
+       }
+       -re "A file or directory .* does not exist..\r\n$gdb_prompt $" {
+           pass "$description (no source available)"
+       }
+       -re ".*$gdb_prompt $" {
+           fail "$description"
+       }
+       timeout {
+           fail "$description (timeout)"
+       }
+    }
+
+    # start the "xgdb" process
+    send_gdb "continue\n"
+    gdb_expect {
+       -re "GNU gdb \[0-9\.\]*.*
+Copyright \[0-9\]* Free Software Foundation, Inc.*
+GDB is free software, covered by the GNU General Public License, and you are.*
+welcome to change it and/or distribute copies of it under certain conditions.*
+Type \"show copying\" to see the conditions.*
+There is absolutely no warranty for GDB.  Type \"show warranty\" for details.*
+This GDB was configured as .*$gdb_prompt $"\
+           { pass "xgdb is at prompt" }
+       -re "GDB is free software and you are welcome to distribute copies of it.*
+ under certain conditions; type \"show copying\" to see the conditions..*
+There is absolutely no warranty for GDB; type \"show warranty\" for details..*
+GDB.*Copyright \[0-9\]+ Free Software Foundation, Inc..*$gdb_prompt $"\
+           { pass "xgdb is at prompt (obsolescent gdb)" }
+       -re ".*$gdb_prompt $"       { fail "xgdb is at prompt" }
+       timeout             { fail "(timeout) xgdb is at prompt" }
+    }
+    
+    # set xgdb prompt so we can tell which is which
+    send_gdb "set prompt (xgdb) \n"
+    gdb_expect {
+       -re "\[(\]xgdb\[)\].*\[(\]xgdb\[)\] $"  { pass "Set xgdb prompt" }
+       -re ".*$gdb_prompt $"           { fail "Set xgdb prompt" }
+       default                         { fail "(timeout) Set xgdb prompt" }
+    }
+    
+    # kill the xgdb process
+    set description "send ^C to child process"
+    send_gdb "\003"
+    gdb_expect {
+       -re "Program received signal SIGINT.*$gdb_prompt $" {
+           pass "$description"
+       }
+       -re ".*$gdb_prompt $" {
+           fail "$description"
+       }
+       timeout {
+           fail "$description (timeout)"
+       }
+    }
+    
+    set description "send SIGINT signal to child process"
+    send_gdb "signal SIGINT\n"
+    gdb_expect {
+       -re "Continuing with signal SIGINT.*$gdb_prompt $" {
+           pass "$description"
+       }
+       -re ".*$gdb_prompt $" {
+           fail "$description"
+       }
+       timeout {
+           fail "$description (timeout)"
+       }
+    }
+    
+    # get a stack trace
+    #
+    # This fails on some linux systems for unknown reasons.  On the
+    # systems where it fails, sometimes it works fine when run manually.
+    # The testsuite failures may not be limited to just aout systems.
+    setup_xfail "i*86-pc-linuxaout-gnu"
+    set description "backtrace through signal handler"
+    send_gdb "backtrace\n"
+    gdb_expect {
+       -re "#0.*(read|poll).*in main \\(.*\\) at .*gdb\\.c.*$gdb_prompt $" {
+           pass "$description"
+       }
+       -re ".*$gdb_prompt $" {
+           # On the alpha, we hit the infamous problem about gdb
+           # being unable to get the frame pointer (mentioned in
+           # gdb/README).  As it is intermittent, there is no way to
+           # XFAIL it which will give us an XPASS if the problem goes
+           # away.
+           setup_xfail "alpha*-*-osf*"
+           fail "$description"
+       }
+       timeout {
+           fail "$description (timeout)"
+       }
+    }
+
+
+    # Set the timeout back to the value it had when we were called.
+    set timeout $oldtimeout
+    verbose "Timeout is now $timeout seconds" 2
+
+    # Restart gdb in case next test expects it to be started already.
+    return 0
+}
+
+# Find a pathname to a file that we would execute if the shell was asked
+# to run $arg using the current PATH.
+
+proc find_gdb { arg } {
+
+    # If the arg directly specifies an existing executable file, then
+    # simply use it.
+
+    if [file executable $arg] then {
+       return $arg
+    }
+
+    set result [which $arg]
+    if [string match "/" [ string range $result 0 0 ]] then {
+       return $result
+    }
+
+    # If everything fails, just return the unqualified pathname as default
+    # and hope for best.
+
+    return $arg
+}
+
+# Run the test with self.
+# Copy the file executable file in case this OS doesn't like to edit its own
+# text space.
+
+set GDB_FULLPATH [find_gdb $GDB]
+
+# Remove any old copy lying around.
+remote_file host delete x$tool
+
+gdb_start
+set file [remote_download host $GDB_FULLPATH x$tool]
+set result [test_with_self $file];
+gdb_exit;
+catch "remote_file host delete $file";
+
+if {$result <0} then {
+    warning "Couldn't test self"
+    return -1
+}
diff --git a/gdb/testsuite/gdb.java/jmain.exp b/gdb/testsuite/gdb.java/jmain.exp
new file mode 100644 (file)
index 0000000..49e7ca3
--- /dev/null
@@ -0,0 +1,67 @@
+# Copyright 2000, 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# This file was based on jmisc.exp which in turn was written by
+# Anthony Green. (green@redhat.com)
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+load_lib "java.exp"
+
+set testfile "jmain"
+set srcfile ${srcdir}/$subdir/${testfile}.java
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [compile_java_from_source ${srcfile} ${binfile} "-g"] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+# Check that plain old "main" works.  The load should both set the
+# language to java and (since --main=jmain), some how set the scope to
+# jmain's main.
+
+# Where the breakpoint should always land
+
+set bpmain "Breakpoint .* file .*jmain.java, line 5\."
+
+gdb_load "${binfile}"
+setup_kfail *-*-* java/1567
+gdb_test "break main" "${bpmain}"
+
+# Check that an unqualified "main" works.
+
+
+gdb_load "${binfile}"
+setup_kfail *-*-* java/1565
+gdb_test "break jmain.main" "${bpmain}"
+
+# Check that a fully qualified "main" works.
+gdb_load "${binfile}"
+setup_xfail *-*-* gcc/16439
+gdb_test "break \'${testfile}.main(java.lang.String\[\])\'" "${bpmain}"
diff --git a/gdb/testsuite/gdb.java/jmain.java b/gdb/testsuite/gdb.java/jmain.java
new file mode 100644 (file)
index 0000000..ee5c8bb
--- /dev/null
@@ -0,0 +1,7 @@
+public class jmain
+{
+  public static void main (String[] args)
+    {
+       return;
+    }
+}
diff --git a/gdb/testsuite/gdb.stabs/exclfwd.exp b/gdb/testsuite/gdb.stabs/exclfwd.exp
new file mode 100644 (file)
index 0000000..05ab97c
--- /dev/null
@@ -0,0 +1,72 @@
+#   Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile exclfwd
+set binfile ${objdir}/${subdir}/${testfile}
+
+foreach file {exclfwd1 exclfwd2} {
+    if {[gdb_compile "${srcdir}/${subdir}/${file}.c" "${file}.o" object {debug}] != ""} {
+        gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+    }
+}
+
+if {[gdb_compile "exclfwd1.o exclfwd2.o" ${binfile} executable {debug}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+get_debug_format
+
+set eol "\[ \t\]*\[\n\r\]+"
+
+gdb_test "ptype v1" "type = struct a {$eol
+    int x;$eol
+    int y;$eol
+}$eol"
+
+if { [test_debug_format "stabs"] } then {
+    setup_kfail "gdb/1602" *-*-*
+}
+gdb_test "ptype v2" "type = struct a {$eol
+    const char .c;$eol
+}$eol"
+
+if { [test_debug_format "stabs"] } then {
+    setup_kfail "gdb/1603" *-*-*
+}
+gdb_test "ptype v3" "type = const char ."
diff --git a/gdb/testsuite/gdb.stabs/exclfwd.h b/gdb/testsuite/gdb.stabs/exclfwd.h
new file mode 100644 (file)
index 0000000..3f064b1
--- /dev/null
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@gnu.org  */
+
+typedef struct a a_t;
diff --git a/gdb/testsuite/gdb.stabs/exclfwd1.c b/gdb/testsuite/gdb.stabs/exclfwd1.c
new file mode 100644 (file)
index 0000000..a7574e5
--- /dev/null
@@ -0,0 +1,34 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@gnu.org  */
+
+#include "exclfwd.h"
+
+struct a 
+{
+  int x, y;
+};
+
+a_t v1;
+
+int
+main ()
+{
+}
diff --git a/gdb/testsuite/gdb.stabs/exclfwd2.c b/gdb/testsuite/gdb.stabs/exclfwd2.c
new file mode 100644 (file)
index 0000000..f7de015
--- /dev/null
@@ -0,0 +1,30 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   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.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@gnu.org  */
+
+#include "exclfwd.h"
+
+struct a
+{
+  const char *c;
+};
+
+a_t v2;
+const char *v3;
diff --git a/gdb/testsuite/gdb.threads/bp_in_thread.exp b/gdb/testsuite/gdb.threads/bp_in_thread.exp
new file mode 100644 (file)
index 0000000..e9dfadb
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# gdb 6.1.1 on AIX had a bug where the aix-threads code called
+# getthrds() incorrectly so that gdb lost track of breakpoints.
+# GDB reported a SIGTRAP signal in a random thread when hitting
+# a breakpoint.
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set testfile "pthread_cond_wait"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "break noreturn" \
+         "Breakpoint 1 at .*: file .*${srcfile}, line .*" \
+         "breakpoint on noreturn"
+
+# Run the program and make sure GDB reports that we stopped after
+# hitting breakpoint 1 in noreturn().
+
+gdb_test "run" \
+         ".*Breakpoint 1, noreturn ().*" \
+         "run to noreturn"
+
diff --git a/gdb/testsuite/gdb.threads/manythreads.c b/gdb/testsuite/gdb.threads/manythreads.c
new file mode 100644 (file)
index 0000000..e39412c
--- /dev/null
@@ -0,0 +1,68 @@
+/* Manythreads test program.
+   Copyright 2004
+   Free Software Foundation, Inc.
+
+   Written by Jeff Johnston <jjohnstn@redhat.com> 
+   Contributed by Red Hat
+
+   This file is part of GDB.
+
+   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.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <limits.h>
+
+void *
+thread_function (void *arg)
+{
+  int x = (int)arg;
+
+  printf ("Thread <%d> executing\n", x);
+
+  return NULL;
+}
+
+int 
+main (int argc, char **argv)
+{
+  pthread_attr_t attr;
+  pthread_t threads[256];
+  int i, j;
+
+  pthread_attr_init (&attr);
+  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+  /* Create a ton of quick-executing threads, then wait for them to
+     complete.  */
+  for (i = 0; i < 1000; ++i) 
+    {
+      for (j = 0; j < 256; ++j)
+       {
+         pthread_create (&threads[j], &attr, thread_function, 
+                         (void *)(i * 1000 + j));
+       }
+
+      for (j = 0; j < 256; ++j)
+       {
+         pthread_join (threads[j], NULL);
+       }
+    }
+
+  pthread_attr_destroy (&attr);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/manythreads.exp b/gdb/testsuite/gdb.threads/manythreads.exp
new file mode 100644 (file)
index 0000000..a2baf84
--- /dev/null
@@ -0,0 +1,127 @@
+# manythreads.exp -- Expect script to test stopping many threads
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Johnston. (jjohnstn@redhat.com)
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "manythreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" ""
+runto_main
+
+# We'll need this when we send_gdb a ^C to GDB.  Need to do it before we
+# run the program and gdb starts saving and restoring tty states.
+# On Ultrix, we don't need it and it is really slow (because shell_escape
+# doesn't use vfork).
+if ![istarget "*-*-ultrix*"] then {
+    gdb_test "shell stty intr '^C'" ""
+}
+
+set message "first continue"
+gdb_test_multiple "continue" "first continue" {
+  -re "error:.*$gdb_prompt $" {
+    fail "$message"
+  }
+  -re "Continuing" {
+    pass "$message"
+  }
+}
+
+# Send a Ctrl-C and verify that we can do info threads and continue
+after 1000
+send_gdb "\003"
+set message "stop threads 1"
+gdb_test_multiple "" "stop threads 1" {
+  -re "\\\[New \[^\]\]*\\\]\r\n" {
+    exp_continue
+  }
+  -re "\\\[\[^\]\]* exited\\\]\r\n" {
+    exp_continue
+  }
+  -re "Thread \[^\n\]* executing\r\n" {
+    exp_continue
+  }
+  -re "Program received signal SIGINT.*$gdb_prompt $" {
+    pass "$message"
+  }
+  timeout {
+    fail "$message (timeout)"
+  }
+}
+
+gdb_test "info threads" ".*1 Thread.*.LWP.*"
+
+set message "second continue"
+gdb_test_multiple "continue" "second continue" {
+  -re "error:.*$gdb_prompt $" {
+    fail "$message"
+  }
+  -re "Continuing" {
+    pass "$message"
+  }
+}
+
+# Send another Ctrl-C and verify that we can do info threads and quit
+after 1000
+send_gdb "\003"
+set message "stop threads 2"
+gdb_test_multiple "" "stop threads 2" {
+  -re "\\\[New \[^\]\]*\\\]\r\n" {
+    exp_continue
+  }
+  -re "\\\[\[^\]\]* exited\\\]\r\n" {
+    exp_continue
+  }
+  -re "Thread \[^\n\]* executing\r\n" {
+    exp_continue
+  }
+  -re "Program received signal SIGINT.*$gdb_prompt $" {
+    pass "stop threads 2"
+  }
+} 
+
+gdb_test_multiple "quit" "GDB exits after stopping multithreaded program" {
+    -re "The program is running.  Exit anyway\\? \\(y or n\\) $" {
+       send_gdb "y\n"
+       exp_continue
+    }
+    eof {
+        pass "GDB exits after stopping multithreaded program"
+    }
+    timeout {
+        fail "GDB exits after stopping multithreaded program (timeout)"
+    }
+}
+
diff --git a/gdb/testsuite/gdb.threads/pthread_cond_wait.c b/gdb/testsuite/gdb.threads/pthread_cond_wait.c
new file mode 100644 (file)
index 0000000..ae87f8c
--- /dev/null
@@ -0,0 +1,76 @@
+/* A small multi-threaded test case.
+
+   Copyright 2004
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+  pthread_mutex_lock(mut);
+  pthread_cond_wait (cond, mut);
+  pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+  pthread_mutex_t mut;
+  pthread_cond_t cond;
+
+  pthread_mutex_init (&mut, NULL);
+  pthread_cond_init (&cond, NULL);
+
+  /* Wait for a condition that will never be signaled, so we effectively
+     block the thread here.  */
+  cond_wait (&cond, &mut);
+}
+
+void *
+forever_pthread (void *unused)
+{
+  noreturn ();
+}
+
+void
+break_me (void)
+{
+  /* Just an anchor to help putting a breakpoint.  */
+}
+
+int
+main (void)
+{
+  pthread_t forever;
+  const struct timespec ts = { 0, 10000000 }; /* 0.01 sec */
+
+  pthread_create (&forever, NULL, forever_pthread, NULL);
+  for (;;)
+    {
+      nanosleep (&ts, NULL);
+      break_me();
+    }
+
+  return 0;
+}
+
diff --git a/gdb/testsuite/gdb.threads/pthread_cond_wait.exp b/gdb/testsuite/gdb.threads/pthread_cond_wait.exp
new file mode 100644 (file)
index 0000000..72ae03a
--- /dev/null
@@ -0,0 +1,73 @@
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file verifies that GDB is able to compute a backtrace for a thread
+# being blocked on a call to pthread_cond_wait(). 
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set testfile "pthread_cond_wait"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "break break_me" \
+    "Breakpoint 1 at .*: file .*${srcfile}, line .*" \
+         "breakpoint on break_me"
+
+gdb_test "run" \
+         ".*Breakpoint 1, break_me ().*" \
+         "run to break_me"
+
+# 
+# Backtrace all threads, find the one running noreturn, and
+# verify that we are able to get a sensible backtrace, including
+# the frame for the pthread_cond_wait() call.
+#
+# The string below will only match if the functions named
+# occur in a single thread's backtrace, in the given order.
+#
+
+global hex
+global decimal
+
+#
+# This is a "backtrace break" ("btb"):
+#
+set btb "\[^\r\n\]+\[\r\n\]+\#${decimal}\[ \t\]+${hex} in "
+
+# One of the threads is blocked on a call to pthread_cond_wait, and
+# we want to verify that we are able to get a sensible backtrace for
+# that thread.  Because we don't know its thread ID, we can't switch
+# to it before doing the backtrace. So we get a backtrace for all
+# threads, and verify that one them returns the expected backtrace.
+gdb_test "thread apply all backtrace" \
+    "pthread_cond_wait${btb}cond_wait${btb}noreturn${btb}forever_pthread.*" \
+    "backtrace in blocked thread"
+
diff --git a/gdb/testsuite/gdb.threads/staticthreads.c b/gdb/testsuite/gdb.threads/staticthreads.c
new file mode 100644 (file)
index 0000000..57defef
--- /dev/null
@@ -0,0 +1,73 @@
+/* This test program is part of GDB, The GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   Originally written by Jeff Johnston <jjohnstn@redhat.com>,
+   contributed by Red Hat
+
+   This file is part of GDB.
+
+   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.  */
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+
+sem_t semaphore;
+
+void *
+thread_function (void *arg)
+{
+  printf ("Thread executing\n");
+  while (sem_wait (&semaphore) != 0)
+    {
+      if (errno != EINTR)
+       {
+         perror ("thread_function");
+         return;
+       }
+    }
+  return NULL;
+}
+
+int 
+main (int argc, char **argv)
+{
+  pthread_attr_t attr;
+
+  pthread_attr_init (&attr);
+  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+  if (sem_init (&semaphore, 0, 0) == -1)
+    {
+      perror ("semaphore");
+      return -1;
+    }
+
+
+  /* Create a thread, wait for it to complete.  */
+  {
+    pthread_t thread;
+    pthread_create (&thread, &attr, thread_function, NULL);
+    sem_post (&semaphore);
+    pthread_join (thread, NULL);
+  }
+
+  pthread_attr_destroy (&attr);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/staticthreads.exp b/gdb/testsuite/gdb.threads/staticthreads.exp
new file mode 100644 (file)
index 0000000..bf04fa3
--- /dev/null
@@ -0,0 +1,95 @@
+# static.exp -- test script, for GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Based on manythreads written by Jeff Johnston, contributed by Red
+# Hat.
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "staticthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set static_flag "-static"
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+        executable \
+        [list debug "incdir=${objdir}" "additional_flags=${static_flag}" \
+            ]] != "" } {
+    return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" ""
+
+
+# See if the static multi-threaded program runs.
+
+runto_main
+gdb_test "break sem_post"
+set test "Continue to main's call of sem_post"
+gdb_test_multiple "continue" "$test" {
+    -re " sem_post .*$gdb_prompt " {
+       pass "$test"
+    }
+    -re "Program received signal .*$gdb_prompt " {
+       kfail gdb/1328 "$test"
+    }
+}
+    
+
+# See if handle SIG32 helps (a little) with a static multi-threaded
+# program.
+
+rerun_to_main
+gdb_test "handle SIG32 nostop noprint pass"
+set test "Handle SIG32 helps"
+gdb_test "continue" " sem_post .*" "handle SIG32 helps"
+
+
+# See if info threads produces anything approaching a thread list.
+
+set test "info threads"
+gdb_test_multiple "info threads" "$test" {
+    -re " Thread .*$gdb_prompt " {
+       pass "$test"
+    }
+    -re "$gdb_prompt " {
+       kfail gdb/1328 "$test"
+    }
+}
+
+
+# Check that the program can be quit.
+
+set test "GDB exits with static thread program"
+gdb_test_multiple "quit" "$test" {
+    -re "The program is running.  Exit anyway\\? \\(y or n\\) $" {
+       send_gdb "y\n"
+       exp_continue
+    }
+    eof {
+        pass "$test"
+    }
+}
diff --git a/gdb/testsuite/gdb.threads/thread_check.c b/gdb/testsuite/gdb.threads/thread_check.c
new file mode 100644 (file)
index 0000000..58cb79e
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+* Copyright (C) 2004 Free Software Foundation, Inc.
+
+* 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.
+
+* This file was written by Steve Munroe. (sjmunroe@us.ibm.com)
+* Test break points and single step on thread functions.
+*/
+
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#define N       2
+
+static void *
+tf (void *arg)
+{
+    int n = (int) (long int) arg;
+    char number[160];
+    int unslept = 10;
+
+    sprintf(number, "tf(%ld): begin", (long)arg);
+    puts (number);
+
+    while (unslept > 0)
+        unslept = sleep(unslept);
+
+    sprintf(number, "tf(%ld): end", (long)arg);
+    puts (number);
+    return NULL;
+}
+
+int main (int argc, char *argv[])
+{
+    int n;
+    int unslept = 2;
+    pthread_t th[N];
+
+    for (n = 0; n < N; ++n)
+    if (pthread_create (&th[n], NULL, tf, (void *) (long int) n) != 0)
+    {
+        while (unslept > 0)
+           unslept = sleep(2);
+        puts ("create failed");
+        exit (1);
+    }
+
+    puts("after create");
+
+    for (n = 0; n < N; ++n)
+    if (pthread_join (th[n], NULL) != 0)
+    {
+        puts ("join failed");
+        exit (1);
+    }
+
+    puts("after join");
+    return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/thread_check.exp b/gdb/testsuite/gdb.threads/thread_check.exp
new file mode 100644 (file)
index 0000000..95b89d0
--- /dev/null
@@ -0,0 +1,96 @@
+# Copyright (C) 2004 Free Software Foundation, Inc.
+
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Manoj Iyer. (manjo@austin.ibm.com)
+# Test break points and single step on thread functions.
+# 
+# Test Purpose:
+# - Test that breakpoints, continue in a threaded  application works. 
+#   On powerpc64-unknown-linux-gnu system, running kernel version
+#   2.6.5-7.71-pseries64 this test is known to fail due to kernel bug
+#   in ptrace system call.
+#
+# Test Strategy:
+# - tbug.c creates 2 threads
+# - start gdb 
+# - create 2 breakpoints #1 main() #2 tf() (the thread function)
+# - run gdb till #1 main() breakpoint is reached
+# - continue to breakpoint #2 tf()
+# - delete all breakpoints 
+# - exit gdb.
+
+if $tracelevel then {
+        strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "thread_check"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+   fail "Can't run to main"
+      return 1;
+}
+
+
+#
+# set breakpoint at thread fucntion tf
+#
+gdb_test "break tf" \
+    "Breakpoint.*at.* file .*$srcfile, line.*" \
+    "breakpoint at tf"
+
+
+#
+#
+# continue to tf() breakpoint #2
+#
+gdb_test "continue" \
+    ".*Breakpoint 2.*tf.* at .*tbug.* .*\r\n.*$gdb_prompt $" \
+     "continue to tf"
+
+#   
+# backtrace from thread function.
+#
+gdb_test "backtrace" \
+    "#0 .*tf .*at .*tbug.*" \
+    "backtrace from thread function"
+
+
+#
+# delete all breakpoints
+#
+delete_breakpoints
+
+#
+# exit gdb
+#
+gdb_exit
diff --git a/gdb/testsuite/gdb.threads/watchthreads.exp b/gdb/testsuite/gdb.threads/watchthreads.exp
new file mode 100644 (file)
index 0000000..d6e89d9
--- /dev/null
@@ -0,0 +1,125 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Check that GDB can support multiple watchpoints across threads.
+
+if $tracelevel {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This test verifies that a watchpoint is detected in the proper thread
+# so the test is only meaningful on a system with hardware watchpoints.
+if [target_info exists gdb,no_hardware_watchpoints] {
+    return 0;
+}
+
+set testfile "schedlock"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set can-use-hw-watchpoints 1" "" ""
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+    gdb_suppress_tests
+}
+
+set args_0 0
+set args_1 0
+
+# Watch values that will be modified by distinct threads.
+gdb_test "watch args\[0\]" "Hardware watchpoint 2: args\\\[0\\\]"
+gdb_test "watch args\[1\]" "Hardware watchpoint 3: args\\\[1\\\]"
+
+# Loop and continue to allow both watchpoints to be triggered.
+for {set i 0} {$i < 30} {incr i} {
+  set test_flag 0
+  gdb_test_multiple "continue" "threaded watch loop" {
+    -re "Hardware watchpoint 2: args\\\[0\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*schedlock.c:21.*$gdb_prompt $"
+       { set args_0 1; set test_flag 1 }
+    -re "Hardware watchpoint 3: args\\\[1\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*schedlock.c:21.*$gdb_prompt $"
+       { set args_1 1; set test_flag 1 }
+    -re "Hardware watchpoint 2: args\\\[0\\\].*Old value = $args_0.*New value = [expr $args_0+1].*in thread_function \\\(arg=0x0\\\) at .*schedlock.c:42.*$gdb_prompt $"
+       { set args_0 [expr $args_0+1]; set test_flag 1 }
+    -re "Hardware watchpoint 3: args\\\[1\\\].*Old value = $args_1.*New value = [expr $args_1+1].*in thread_function \\\(arg=0x1\\\) at .*schedlock.c:42.*$gdb_prompt $"
+       { set args_1 [expr $args_1+1]; set test_flag 1 }
+  }
+  # If we fail above, don't bother continuing loop
+  if { $test_flag == 0 } {
+    set i 30;
+  }
+}
+
+# Print success message if loop succeeded.
+if { $test_flag == 1 } {
+  pass "threaded watch loop"
+}
+
+# Verify that we hit first watchpoint in main thread.
+set message "first watchpoint on args\[0\] hit"
+if { $args_0 > 0 } {
+  pass $message 
+} else {
+  fail $message 
+}
+
+# Verify that we hit second watchpoint in main thread.
+set message "first watchpoint on args\[1\] hit"
+if { $args_1 > 0 } {
+  pass $message 
+} else {
+  fail $message 
+}
+
+# Verify that we hit first watchpoint in child thread.
+set message "watchpoint on args\[0\] hit in thread"
+if { $args_0 > 1 } {
+  pass $message 
+} else {
+  fail $message
+}
+
+# Verify that we hit second watchpoint in child thread.
+set message "watchpoint on args\[1\] hit in thread"
+if { $args_1 > 1 } {
+  pass $message 
+} else {
+  fail $message 
+}
+
+# Verify that all watchpoint hits are accounted for.
+set message "combination of threaded watchpoints = 30"
+if { [expr $args_0+$args_1] == 30 } {
+  pass $message 
+} else {
+  fail $message 
+}
diff --git a/gdb/testsuite/lib/cp-support.exp b/gdb/testsuite/lib/cp-support.exp
new file mode 100644 (file)
index 0000000..7ce1e48
--- /dev/null
@@ -0,0 +1,469 @@
+# This test code is part of GDB, the GNU debugger.
+
+# Copyright 2003, 2004 Free Software Foundation, Inc.
+
+# 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.  
+
+# Auxiliary function to check for known problems.
+#
+# EXPECTED_STRING is the string expected by the test.
+#
+# ACTUAL_STRING is the actual string output by gdb.
+#
+# ERRATA_TABLE is a list of lines of the form:
+#
+#  { expected-string broken-string {eval-block} }
+#
+# If there is a line for the given EXPECTED_STRING, and if the
+# ACTUAL_STRING output by gdb is the same as the BROKEN_STRING in the
+# table, then I eval the eval-block.
+
+proc cp_check_errata { expected_string actual_string errata_table } {
+    foreach erratum $errata_table {
+       if { "$expected_string" == [lindex $erratum 0]
+       &&   "$actual_string"   == [lindex $erratum 1] } then {
+           eval [lindex $erratum 2]
+       }
+    }
+}
+
+# Test ptype of a class.
+#
+# Different C++ compilers produce different output.  To accommodate all
+# the variations listed below, I read the output of "ptype" and process
+# each line, matching it to the class description given in the
+# parameters.
+#
+# IN_COMMAND and IN_TESTNAME are the command and testname for
+# gdb_test_multiple.  If IN_TESTNAME is the empty string, then it
+# defaults to IN_COMMAND.
+#
+# IN_KEY is "class" or "struct".  For now, I ignore it, and allow either
+# "class" or "struct" in the output, as long as the access specifiers all
+# work out okay.
+#
+# IN_TAG is the class tag or structure tag.
+#
+# IN_CLASS_TABLE is a list of class information.  Each entry contains a
+# keyword and some values.  The keywords and their values are:
+#
+#   { base "base-declaration" }
+#
+#      the class has a base with the given declaration.
+#
+#   { vbase "name" }
+#
+#      the class has a virtual base pointer with the given name.  this
+#      is for gcc 2.95.3, which emits ptype entries for the virtual base
+#      pointers.  the vbase list includes both indirect and direct
+#      virtual base classes (indeed, a virtual base is usually
+#      indirect), so this information cannot be derived from the base
+#      declarations.
+#
+#   { field "access" "declaration" }
+#
+#      the class has a data field with the given access type and the
+#      given declaration.
+#
+#   { method "access" "declaration" }
+#
+#      the class has a member function with the given access type
+#      and the given declaration.
+#
+# If you test the same class declaration more than once, you can specify
+# IN_CLASS_TABLE as "ibid".  "ibid" means: look for a previous class
+# table that had the same IN_KEY and IN_TAG, and re-use that table.
+#
+# IN_TAIL is the expected text after the close brace, specifically the "*"
+# in "struct { ... } *".  This is an optional parameter.  The default
+# value is "", for no tail.
+#
+# IN_ERRATA_TABLE is a list of errata entries.  See cp_check_errata for the
+# format of the errata table.  Note: the errata entries are not subject to
+# demangler syntax adjustment, so you have to make a bigger table
+# with lines for each output variation.
+# 
+# gdb can vary the output of ptype in several ways:
+#
+# . CLASS/STRUCT
+#
+#   The output can start with either "class" or "struct", depending on
+#   what the symbol table reader in gdb decides.  This is usually
+#   unrelated to the original source code.
+#
+#     dwarf-2  debug info distinguishes class/struct, but gdb ignores it
+#     stabs+   debug info does not distinguish class/struct
+#     hp       debug info distinguishes class/struct, and gdb honors it
+#
+#   I tried to accommodate this with regular expressions such as
+#   "((class|struct) A \{ public:|struct A \{)", but that turns into a
+#   hairy mess because of optional private virtual base pointers and
+#   optional public synthetic operators.  This is the big reason I gave
+#   up on regular expressions and started parsing the output.
+#
+# . REDUNDANT ACCESS SPECIFIER
+#
+#   In "class { private: ... }" or "struct { public: ... }", gdb might
+#   or might not emit a redundant initial access specifier, depending
+#   on the gcc version.
+#
+# . VIRTUAL BASE POINTERS
+#
+#   If a class has virtual bases, either direct or indirect, the class
+#   will have virtual base pointers.  With gcc 2.95.3, gdb prints lines
+#   for these virtual base pointers.  This does not happen with gcc
+#   3.3.4, gcc 3.4.1, or hp acc A.03.45.
+#
+#   I accept these lines.  These lines are optional; but if I see one of
+#   these lines, then I expect to see all of them.
+#
+#   Note: drow considers printing these lines to be a bug in gdb.
+#
+# . SYNTHETIC METHODS
+#
+#   A C++ compiler may synthesize some methods: an assignment
+#   operator, a copy constructor, a constructor, and a destructor.  The
+#   compiler might include debug information for these methods.
+#
+#     dwarf-2  gdb does not show these methods
+#     stabs+   gdb shows these methods
+#     hp       gdb does not show these methods
+#
+#   I accept these methods.  These lines are optional, and any or
+#   all of them might appear, mixed in anywhere in the regular methods.
+#
+#   With gcc v2, the synthetic copy-ctor and ctor have an additional
+#   "int" parameter at the beginning, the "in-charge" flag.
+#
+# . DEMANGLER SYNTAX VARIATIONS
+#
+#   Different demanglers produce "int foo(void)" versus "int foo()",
+#   "const A&" versus "const A &", and so on.
+#
+# TESTED WITH
+#
+#   gcc 2.95.3 -gdwarf-2
+#   gcc 2.95.3 -gstabs+
+#   gcc 3.3.4 -gdwarf-2
+#   gcc 3.3.4 -gstabs+
+#   gcc 3.4.1 -gdwarf-2
+#   gcc 3.4.1 -gstabs+
+#   gcc HEAD 20040731 -gdwarf-2
+#   gcc HEAD 20040731 -gstabs+
+# 
+# TODO
+#
+# Tagless structs.
+#
+# "A*" versus "A *" and "A&" versus "A &" in user methods.
+#
+# Test with hp ACC.
+#
+# -- chastain 2004-08-07
+
+proc cp_test_ptype_class { in_command in_testname in_key in_tag in_class_table { in_tail "" } { in_errata_table { } } } {
+    global gdb_prompt
+    set wsopt "\[\r\n\t \]*"
+
+    # The test name defaults to the command.
+
+    if { "$in_testname" == "" } then { set in_testname "$in_command" }
+
+    # Save class tables in a history array for reuse.
+
+    global cp_class_table_history
+    if { $in_class_table == "ibid" } then {
+       if { ! [info exists cp_class_table_history("$in_key,$in_tag") ] } then {
+           fail "$in_testname // bad ibid"
+           return
+       }
+       set in_class_table $cp_class_table_history("$in_key,$in_tag")
+    } else {
+       set cp_class_table_history("$in_key,$in_tag") $in_class_table
+    }
+
+    # Split the class table into separate tables.
+
+    set list_bases   { }
+    set list_vbases  { }
+    set list_fields  { }
+    set list_methods { }
+
+    foreach class_line $in_class_table {
+       switch [lindex $class_line 0] {
+           "base"   { lappend list_bases   [lindex $class_line 1] }
+           "vbase"  { lappend list_vbases  [lindex $class_line 1] }
+           "field"  { lappend list_fields  [lrange $class_line 1 2] }
+           "method" { lappend list_methods [lrange $class_line 1 2] }
+           default  { fail "$in_testname // bad line in class table: $class_line"; return; }
+       }
+    }
+
+    # Construct a list of synthetic operators.
+    # These are: { count ccess-type regular-expression }.
+
+    set list_synth { }
+    lappend list_synth [list 0 "public" "$in_tag & operator=\\($in_tag const ?&\\);"]
+    lappend list_synth [list 0 "public" "$in_tag\\((int,|) ?$in_tag const ?&\\);"]
+    lappend list_synth [list 0 "public" "$in_tag\\((int|void|)\\);"]
+
+    # Actually do the ptype.
+
+    set parse_okay 0
+    gdb_test_multiple "$in_command" "$in_testname // parse failed" {
+       -re "type = (struct|class)${wsopt}(\[A-Za-z0-9_\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" {
+           set parse_okay          1
+           set actual_key          $expect_out(1,string)
+           set actual_tag          $expect_out(2,string)
+           set actual_base_string  $expect_out(3,string)
+           set actual_body         $expect_out(5,string)
+           set actual_tail         $expect_out(6,string)
+       }
+    }
+    if { ! $parse_okay } then { return }
+
+    # Check the actual key.  It would be nice to require that it match
+    # the input key, but gdb does not support that.  For now, accept any
+    # $actual_key as long as the access property of each field/method
+    # matches.
+
+    switch "$actual_key" {
+       "class"  { set access "private" }
+       "struct" { set access "public"  }
+       default  {
+           cp_check_errata "class"  "$actual_key" $in_errata_table
+           cp_check_errata "struct" "$actual_key" $in_errata_table
+           fail "$in_testname // wrong key: $actual_key"
+           return
+       }
+    }
+
+    # Check the actual tag.
+
+    if { "$actual_tag" != "$in_tag" } then {
+       cp_check_errata "$in_tag" "$actual_tag" $in_errata_table
+       fail "$in_testname // wrong tag: $actual_tag"
+       return
+    }
+
+    # Check the actual bases.
+    # First parse them into a list.
+
+    set list_actual_bases { }
+    if { "$actual_base_string" != "" } then {
+       regsub "^:${wsopt}" $actual_base_string "" actual_base_string
+       set list_actual_bases [split $actual_base_string ","]
+    }
+
+    # Check the base count.
+
+    if { [llength $list_actual_bases] < [llength $list_bases] } then {
+       fail "$in_testname // too few bases"
+       return
+    }
+    if { [llength $list_actual_bases] > [llength $list_bases] } then {
+       fail "$in_testname // too many bases"
+       return
+    }
+
+    # Check each base.
+
+    foreach actual_base $list_actual_bases {
+       set actual_base [string trim $actual_base]
+       set base [lindex $list_bases 0]
+       if { "$actual_base" != "$base" } then {
+           cp_check_errata "$base" "$actual_base" $in_errata_table
+           fail "$in_testname // wrong base: $actual_base"
+           return
+       }
+       set list_bases [lreplace $list_bases 0 0]
+    }
+
+    # Parse each line in the body.
+
+    set last_was_access 0
+    set vbase_match 0
+
+    foreach actual_line [split $actual_body "\r\n"] {
+
+       # Chomp the line.
+
+       set actual_line [string trim $actual_line]
+       if { "$actual_line" == "" } then { continue }
+
+       # Access specifiers.
+
+       if { [regexp "^(public|protected|private)${wsopt}:\$" "$actual_line" s0 s1] } then {
+           set access "$s1"
+           if { $last_was_access } then {
+               fail "$in_testname // redundant access specifier"
+               return
+           }
+           set last_was_access 1
+           continue
+       } else {
+           set last_was_access 0
+       }
+
+       # Optional virtual base pointer.
+
+       if { [ llength $list_vbases ] > 0 } then {
+           set vbase [lindex $list_vbases 0]
+           if { [ regexp "$vbase \\*(_vb.|_vb\\\$|__vb_)\[0-9\]*$vbase;" $actual_line ] } then {
+               if { "$access" != "private" } then {
+                   cp_check_errata "private" "$access" $in_errata_table
+                   fail "$in_testname // wrong access specifier for virtual base: $access"
+                   return
+               }
+               set list_vbases [lreplace $list_vbases 0 0]
+               set vbase_match 1
+               continue
+           }
+       }
+
+       # Data field.
+
+       if { [llength $list_fields] > 0 } then {
+           set field_access [lindex [lindex $list_fields 0] 0]
+           set field_decl   [lindex [lindex $list_fields 0] 1]
+           if { "$actual_line" == "$field_decl" } then {
+               if { "$access" != "$field_access" } then {
+                   cp_check_errata "$field_access" "$access" $in_errata_table
+                   fail "$in_testname // wrong access specifier for field: $access"
+                   return
+               }
+               set list_fields [lreplace $list_fields 0 0]
+               continue
+           }
+
+           # Data fields must appear before synths and methods.
+           cp_check_errata "$field_decl" "$actual_line" $in_errata_table
+           fail "$in_testname // unrecognized line type 1: $actual_line"
+           return
+       }
+
+       # Method function.
+
+       if { [llength $list_methods] > 0 } then {
+           set method_access [lindex [lindex $list_methods 0] 0]
+           set method_decl   [lindex [lindex $list_methods 0] 1]
+           if { "$actual_line" == "$method_decl" } then {
+               if { "$access" != "$method_access" } then {
+                   cp_check_errata "$method_access" "$access" $in_errata_table
+                   fail "$in_testname // wrong access specifier for method: $access"
+                   return
+               }
+               set list_methods [lreplace $list_methods 0 0]
+               continue
+           }
+
+           # gcc 2.95.3 shows "foo()" as "foo(void)".
+           regsub -all "\\(\\)" $method_decl "(void)" method_decl
+           if { "$actual_line" == "$method_decl" } then {
+               if { "$access" != "$method_access" } then {
+                   cp_check_errata "$method_access" "$access" $in_errata_table
+                   fail "$in_testname // wrong access specifier for method: $access"
+                   return
+               }
+               set list_methods [lreplace $list_methods 0 0]
+               continue
+           }
+       }
+
+       # Synthetic operators.  These are optional and can be mixed in
+       # with the methods in any order, but duplicates are wrong.
+       #
+       # This test must come after the user methods, so that a user
+       # method which matches a synth-method pattern is treated
+       # properly as a user method.
+
+       set synth_match 0
+       for { set isynth 0 } { $isynth < [llength $list_synth] } { incr isynth } {
+           set synth         [lindex $list_synth $isynth]
+           set synth_count   [lindex $synth 0]
+           set synth_access  [lindex $synth 1]
+           set synth_re      [lindex $synth 2]
+
+           if { [ regexp "$synth_re" "$actual_line" ] } then {
+
+               if { "$access" != "$synth_access" } then {
+                   cp_check_errata "$synth_access" "$access" $in_errata_table
+                   fail "$in_testname // wrong access specifier for synthetic operator: $access"
+                   return
+               }
+
+               if { $synth_count > 0 } then {
+                   cp_check_errata "$actual_line" "$actual_line" $in_errata_table
+                   fail "$in_testname // duplicate synthetic operator: $actual_line"
+               }
+
+               # Update the count in list_synth.
+
+               incr synth_count 
+               set synth [list $synth_count $synth_access "$synth_re"]
+               set list_synth [lreplace $list_synth $isynth $isynth $synth]
+
+               # Match found.
+
+               set synth_match 1
+               break
+           }
+       }
+       if { $synth_match } then { continue }
+
+       # Unrecognized line.
+
+       if { [llength $list_methods] > 0 } then {
+           set method_decl [lindex [lindex $list_methods 0] 1]
+           cp_check_errata "$method_decl" "$actual_line" $in_errata_table
+       }
+
+       fail "$in_testname // unrecognized line type 2: $actual_line"
+       return
+    }
+
+    # Check for missing elements.
+
+    if { $vbase_match } then {
+       if { [llength $list_vbases] > 0 } then {
+           fail "$in_testname // missing virtual base pointers"
+           return
+       }
+    }
+
+    if { [llength $list_fields] > 0 } then {
+       fail "$in_testname // missing fields"
+       return
+    }
+
+    if { [llength $list_methods] > 0 } then {
+       fail "$in_testname // missing methods"
+       return
+    }
+
+    # Check the tail.
+
+    set actual_tail [string trim $actual_tail]
+    if { "$actual_tail" != "$in_tail" } then {
+       cp_check_errata "$in_tail" "$actual_tail" $in_errata_table
+       fail "$in_testname // wrong tail: $actual_tail"
+       return
+    }
+
+    # It all worked!
+
+    pass "$in_testname"
+    return
+}
diff --git a/gdb/vax-nat.c b/gdb/vax-nat.c
new file mode 100644 (file)
index 0000000..9dc0c51
--- /dev/null
@@ -0,0 +1,106 @@
+/* Native-dependent code for VAX UNIXen (including older BSD's).
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "inferior.h"
+
+#include "gdb_assert.h"
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+
+#ifdef HAVE_SYS_PTRACE_H
+#include <sys/ptrace.h>
+#endif
+
+#ifndef PT_READ_U
+#define PT_READ_U 3
+#endif
+
+#ifdef SYS_REG_H
+/* UNIX 32V and derivatives (including 3BSD).  */
+#include <sys/reg.h>
+#else
+/* 4.2BSD and derivatives.  */
+#include <machine/reg.h>
+#endif
+
+#include "vax-tdep.h"
+
+/* Address of the user structure.  This is the the value for 32V; 3BSD
+   uses a different value, but hey, who's still using those systems?  */
+CORE_ADDR vax_kernel_u_addr = 0x80020000;
+
+/* Location of the user's stored registers; usage is `u.u_ar0[XX]'.
+   For 4.2BSD and ULTRIX these are negative!  See <machine/reg.h>.  */
+static int vax_register_index[] =
+{
+  R0, R1, R2, R3, R4, R5,
+  R6, R7, R8, R9, R10, R11,
+  AP, FP, SP, PC, PS
+};
+
+CORE_ADDR
+vax_register_u_addr (CORE_ADDR u_ar0, int regnum)
+{
+  gdb_assert (regnum >= 0 && regnum < ARRAY_SIZE (vax_register_index));
+
+  /* Type is `int *u_ar0'.  See <sys/user.h>.  */
+  return u_ar0 + vax_register_index[regnum - VAX_R0_REGNUM] * 4;
+}
+\f
+
+CORE_ADDR
+vax_register_u_offset (int regnum)
+{
+  size_t u_ar0_offset = offsetof (struct user, u_ar0);
+  CORE_ADDR u_ar0;
+  int pid;
+
+  errno = 0;
+  pid = PIDGET (inferior_ptid);
+  u_ar0 = ptrace (PT_READ_U, pid, u_ar0_offset, 0);
+  if (errno)
+    perror_with_name ("Unable to determine location of registers");
+
+  return vax_register_u_addr (u_ar0, regnum) - vax_kernel_u_addr;
+}
+\f
+
+#include <nlist.h>
+
+#ifndef _PATH_UNIX
+#define _PATH_UNIX "/vmunix"
+#endif
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_vax_nat (void);
+
+void
+_initialize_vax_nat (void)
+{
+  struct nlist names[2];
+
+  names[0].n_name = "_u";
+  names[1].n_name = NULL;
+  if (nlist (_PATH_UNIX, names) == 0)
+    vax_kernel_u_addr = names[0].n_value;
+}
diff --git a/gdb/vaxbsd-nat.c b/gdb/vaxbsd-nat.c
new file mode 100644 (file)
index 0000000..b00e93d
--- /dev/null
@@ -0,0 +1,138 @@
+/* Native-dependent code for modern VAX BSD's.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "vax-tdep.h"
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
+
+static void
+vaxbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+  const char *regs = gregs;
+  int regnum;
+
+  for (regnum = 0; regnum < VAX_NUM_REGS; regnum++)
+    regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+   in GREGS.  */
+
+static void
+vaxbsd_collect_gregset (const struct regcache *regcache,
+                       void *gregs, int regnum)
+{
+  char *regs = gregs;
+  int i;
+
+  for (i = 0; i <= VAX_NUM_REGS; i++)
+    {
+      if (regnum == -1 || regnum == i)
+       regcache_raw_collect (regcache, i, regs + i * 4);
+    }
+}
+\f
+
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers.  */
+
+void
+fetch_inferior_registers (int regnum)
+{
+  struct reg regs;
+
+  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't get registers");
+
+  vaxbsd_supply_gregset (current_regcache, &regs);
+}
+
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers.  */
+
+void
+store_inferior_registers (int regnum)
+{
+  struct reg regs;
+
+  if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't get registers");
+
+  vaxbsd_collect_gregset (current_regcache, &regs, regnum);
+
+  if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+             (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+    perror_with_name ("Couldn't write registers");
+}
+\f
+
+/* Support for debugging kernel virtual memory images.  */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+vaxbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+  int regnum;
+
+  /* The following is true for OpenBSD 3.5:
+
+     The pcb contains the register state at the context switch inside
+     cpu_switch().  */
+
+  /* The stack pointer shouldn't be zero.  */
+  if (pcb->KSP == 0)
+    return 0;
+
+  for (regnum = VAX_R0_REGNUM; regnum < VAX_AP_REGNUM; regnum++)
+    regcache_raw_supply (regcache, regnum, &pcb->R[regnum - VAX_R0_REGNUM]);
+  regcache_raw_supply (regcache, VAX_AP_REGNUM, &pcb->AP);
+  regcache_raw_supply (regcache, VAX_FP_REGNUM, &pcb->FP);
+  regcache_raw_supply (regcache, VAX_SP_REGNUM, &pcb->KSP);
+  regcache_raw_supply (regcache, VAX_PC_REGNUM, &pcb->PC);
+  regcache_raw_supply (regcache, VAX_PS_REGNUM, &pcb->PSL);
+
+  return 1;
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_vaxbsd_nat (void);
+
+void
+_initialize_vaxbsd_nat (void)
+{
+  /* Support debugging kernel virtual memory images.  */
+  bsd_kvm_add_target (vaxbsd_supply_pcb);
+}
diff --git a/gdb/vaxnbsd-tdep.c b/gdb/vaxnbsd-tdep.c
new file mode 100644 (file)
index 0000000..c324da8
--- /dev/null
@@ -0,0 +1,75 @@
+/* Target-dependent code for NetBSD/vax.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+
+#include "vax-tdep.h"
+#include "solib-svr4.h"
+
+#include "gdb_string.h"
+
+/* Support for shared libraries.  */
+
+/* Return non-zero if we are in a shared library trampoline code stub.  */
+
+int
+vaxnbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+  return (name && !strcmp (name, "_DYNAMIC"));
+}
+\f
+
+/* NetBSD a.out.  */
+
+static void
+vaxnbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  /* Assume SunOS-style shared libraries.  */
+  set_gdbarch_in_solib_call_trampoline
+    (gdbarch, vaxnbsd_aout_in_solib_call_trampoline);
+}
+
+/* NetBSD ELF.  */
+
+static void
+vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  /* NetBSD ELF uses SVR4-style shared libraries.  */
+  set_gdbarch_in_solib_call_trampoline
+    (gdbarch, generic_in_solib_call_trampoline);
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+\f
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_vaxnbsd_tdep (void);
+
+void
+_initialize_vaxnbsd_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_AOUT,
+                         vaxnbsd_aout_init_abi);
+  gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_ELF,
+                         vaxnbsd_elf_init_abi);
+}
diff --git a/include/elf/crx.h b/include/elf/crx.h
new file mode 100644 (file)
index 0000000..33ba005
--- /dev/null
@@ -0,0 +1,53 @@
+/* CRX ELF support for BFD.
+   Copyright 2004 Free Software Foundation, Inc.
+   Contributed by Tomer Levi, NSC, Israel.
+   Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
+   Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
+
+   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_CRX_H
+#define _ELF_CRX_H
+
+#include "elf/reloc-macros.h"
+
+/* Creating indices for reloc_map_index array.  */
+START_RELOC_NUMBERS(elf_crx_reloc_type)
+  RELOC_NUMBER (R_CRX_NONE,           0)
+  RELOC_NUMBER (R_CRX_REL4,           1)
+  RELOC_NUMBER (R_CRX_REL8,           2)
+  RELOC_NUMBER (R_CRX_REL8_CMP,       3)
+  RELOC_NUMBER (R_CRX_REL16,          4)
+  RELOC_NUMBER (R_CRX_REL24,          5)
+  RELOC_NUMBER (R_CRX_REL32,          6)
+  RELOC_NUMBER (R_CRX_REGREL12,       7)
+  RELOC_NUMBER (R_CRX_REGREL22,       8)
+  RELOC_NUMBER (R_CRX_REGREL28,       9)
+  RELOC_NUMBER (R_CRX_REGREL32,       10)
+  RELOC_NUMBER (R_CRX_ABS16,          11)
+  RELOC_NUMBER (R_CRX_ABS32,          12)
+  RELOC_NUMBER (R_CRX_NUM8,          13)
+  RELOC_NUMBER (R_CRX_NUM16,          14)
+  RELOC_NUMBER (R_CRX_NUM32,          15)
+  RELOC_NUMBER (R_CRX_IMM16,         16)
+  RELOC_NUMBER (R_CRX_IMM32,         17)
+  RELOC_NUMBER (R_CRX_SWITCH8,       18)
+  RELOC_NUMBER (R_CRX_SWITCH16,              19)
+  RELOC_NUMBER (R_CRX_SWITCH32,              20)
+END_RELOC_NUMBERS(R_CRX_MAX)
+       
+#endif /* _ELF_CRX_H */
diff --git a/include/gdb/sim-ppc.h b/include/gdb/sim-ppc.h
new file mode 100644 (file)
index 0000000..e31a671
--- /dev/null
@@ -0,0 +1,771 @@
+/* sim-ppc.h --- interface between PowerPC simulator and GDB.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   Contributed by Red Hat.
+
+   This file is part of GDB.
+
+   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.  */
+
+#if !defined (SIM_PPC_H)
+#define SIM_PPC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The register access functions, sim_fetch_register and
+   sim_store_register, use the following numbering for PowerPC
+   registers.  */
+
+enum sim_ppc_regnum
+  {
+    /* General-purpose registers, r0 -- r31.  */
+    sim_ppc_r0_regnum,
+    sim_ppc_r1_regnum,
+    sim_ppc_r2_regnum,
+    sim_ppc_r3_regnum,
+    sim_ppc_r4_regnum,
+    sim_ppc_r5_regnum,
+    sim_ppc_r6_regnum,
+    sim_ppc_r7_regnum,
+    sim_ppc_r8_regnum,
+    sim_ppc_r9_regnum,
+    sim_ppc_r10_regnum,
+    sim_ppc_r11_regnum,
+    sim_ppc_r12_regnum,
+    sim_ppc_r13_regnum,
+    sim_ppc_r14_regnum,
+    sim_ppc_r15_regnum,
+    sim_ppc_r16_regnum,
+    sim_ppc_r17_regnum,
+    sim_ppc_r18_regnum,
+    sim_ppc_r19_regnum,
+    sim_ppc_r20_regnum,
+    sim_ppc_r21_regnum,
+    sim_ppc_r22_regnum,
+    sim_ppc_r23_regnum,
+    sim_ppc_r24_regnum,
+    sim_ppc_r25_regnum,
+    sim_ppc_r26_regnum,
+    sim_ppc_r27_regnum,
+    sim_ppc_r28_regnum,
+    sim_ppc_r29_regnum,
+    sim_ppc_r30_regnum,
+    sim_ppc_r31_regnum,
+
+    /* Floating-point registers, f0 -- f31.  */
+    sim_ppc_f0_regnum,
+    sim_ppc_f1_regnum,
+    sim_ppc_f2_regnum,
+    sim_ppc_f3_regnum,
+    sim_ppc_f4_regnum,
+    sim_ppc_f5_regnum,
+    sim_ppc_f6_regnum,
+    sim_ppc_f7_regnum,
+    sim_ppc_f8_regnum,
+    sim_ppc_f9_regnum,
+    sim_ppc_f10_regnum,
+    sim_ppc_f11_regnum,
+    sim_ppc_f12_regnum,
+    sim_ppc_f13_regnum,
+    sim_ppc_f14_regnum,
+    sim_ppc_f15_regnum,
+    sim_ppc_f16_regnum,
+    sim_ppc_f17_regnum,
+    sim_ppc_f18_regnum,
+    sim_ppc_f19_regnum,
+    sim_ppc_f20_regnum,
+    sim_ppc_f21_regnum,
+    sim_ppc_f22_regnum,
+    sim_ppc_f23_regnum,
+    sim_ppc_f24_regnum,
+    sim_ppc_f25_regnum,
+    sim_ppc_f26_regnum,
+    sim_ppc_f27_regnum,
+    sim_ppc_f28_regnum,
+    sim_ppc_f29_regnum,
+    sim_ppc_f30_regnum,
+    sim_ppc_f31_regnum,
+
+    /* Altivec vector registers, vr0 -- vr31.  */
+    sim_ppc_vr0_regnum,
+    sim_ppc_vr1_regnum,
+    sim_ppc_vr2_regnum,
+    sim_ppc_vr3_regnum,
+    sim_ppc_vr4_regnum,
+    sim_ppc_vr5_regnum,
+    sim_ppc_vr6_regnum,
+    sim_ppc_vr7_regnum,
+    sim_ppc_vr8_regnum,
+    sim_ppc_vr9_regnum,
+    sim_ppc_vr10_regnum,
+    sim_ppc_vr11_regnum,
+    sim_ppc_vr12_regnum,
+    sim_ppc_vr13_regnum,
+    sim_ppc_vr14_regnum,
+    sim_ppc_vr15_regnum,
+    sim_ppc_vr16_regnum,
+    sim_ppc_vr17_regnum,
+    sim_ppc_vr18_regnum,
+    sim_ppc_vr19_regnum,
+    sim_ppc_vr20_regnum,
+    sim_ppc_vr21_regnum,
+    sim_ppc_vr22_regnum,
+    sim_ppc_vr23_regnum,
+    sim_ppc_vr24_regnum,
+    sim_ppc_vr25_regnum,
+    sim_ppc_vr26_regnum,
+    sim_ppc_vr27_regnum,
+    sim_ppc_vr28_regnum,
+    sim_ppc_vr29_regnum,
+    sim_ppc_vr30_regnum,
+    sim_ppc_vr31_regnum,
+
+    /* SPE APU GPR upper halves.  These are the upper 32 bits of the
+       gprs; there is one upper-half register for each gpr, so it is
+       appropriate to use sim_ppc_num_gprs for iterating through
+       these.  */
+    sim_ppc_rh0_regnum,
+    sim_ppc_rh1_regnum,
+    sim_ppc_rh2_regnum,
+    sim_ppc_rh3_regnum,
+    sim_ppc_rh4_regnum,
+    sim_ppc_rh5_regnum,
+    sim_ppc_rh6_regnum,
+    sim_ppc_rh7_regnum,
+    sim_ppc_rh8_regnum,
+    sim_ppc_rh9_regnum,
+    sim_ppc_rh10_regnum,
+    sim_ppc_rh11_regnum,
+    sim_ppc_rh12_regnum,
+    sim_ppc_rh13_regnum,
+    sim_ppc_rh14_regnum,
+    sim_ppc_rh15_regnum,
+    sim_ppc_rh16_regnum,
+    sim_ppc_rh17_regnum,
+    sim_ppc_rh18_regnum,
+    sim_ppc_rh19_regnum,
+    sim_ppc_rh20_regnum,
+    sim_ppc_rh21_regnum,
+    sim_ppc_rh22_regnum,
+    sim_ppc_rh23_regnum,
+    sim_ppc_rh24_regnum,
+    sim_ppc_rh25_regnum,
+    sim_ppc_rh26_regnum,
+    sim_ppc_rh27_regnum,
+    sim_ppc_rh28_regnum,
+    sim_ppc_rh29_regnum,
+    sim_ppc_rh30_regnum,
+    sim_ppc_rh31_regnum,
+
+    /* SPE APU GPR full registers.  Each of these registers is the
+       64-bit concatenation of a 32-bit GPR (providing the lower bits)
+       and a 32-bit upper-half register (providing the higher bits).
+       As for the upper-half registers, it is appropriate to use
+       sim_ppc_num_gprs with these.  */
+    sim_ppc_ev0_regnum,
+    sim_ppc_ev1_regnum,
+    sim_ppc_ev2_regnum,
+    sim_ppc_ev3_regnum,
+    sim_ppc_ev4_regnum,
+    sim_ppc_ev5_regnum,
+    sim_ppc_ev6_regnum,
+    sim_ppc_ev7_regnum,
+    sim_ppc_ev8_regnum,
+    sim_ppc_ev9_regnum,
+    sim_ppc_ev10_regnum,
+    sim_ppc_ev11_regnum,
+    sim_ppc_ev12_regnum,
+    sim_ppc_ev13_regnum,
+    sim_ppc_ev14_regnum,
+    sim_ppc_ev15_regnum,
+    sim_ppc_ev16_regnum,
+    sim_ppc_ev17_regnum,
+    sim_ppc_ev18_regnum,
+    sim_ppc_ev19_regnum,
+    sim_ppc_ev20_regnum,
+    sim_ppc_ev21_regnum,
+    sim_ppc_ev22_regnum,
+    sim_ppc_ev23_regnum,
+    sim_ppc_ev24_regnum,
+    sim_ppc_ev25_regnum,
+    sim_ppc_ev26_regnum,
+    sim_ppc_ev27_regnum,
+    sim_ppc_ev28_regnum,
+    sim_ppc_ev29_regnum,
+    sim_ppc_ev30_regnum,
+    sim_ppc_ev31_regnum,
+
+    /* Segment registers, sr0 -- sr15.  */
+    sim_ppc_sr0_regnum,
+    sim_ppc_sr1_regnum,
+    sim_ppc_sr2_regnum,
+    sim_ppc_sr3_regnum,
+    sim_ppc_sr4_regnum,
+    sim_ppc_sr5_regnum,
+    sim_ppc_sr6_regnum,
+    sim_ppc_sr7_regnum,
+    sim_ppc_sr8_regnum,
+    sim_ppc_sr9_regnum,
+    sim_ppc_sr10_regnum,
+    sim_ppc_sr11_regnum,
+    sim_ppc_sr12_regnum,
+    sim_ppc_sr13_regnum,
+    sim_ppc_sr14_regnum,
+    sim_ppc_sr15_regnum,
+
+    /* Miscellaneous --- but non-SPR --- registers.  */
+    sim_ppc_pc_regnum,
+    sim_ppc_ps_regnum,
+    sim_ppc_cr_regnum,
+    sim_ppc_fpscr_regnum,
+    sim_ppc_acc_regnum,
+    sim_ppc_vscr_regnum,
+
+    /* Special-purpose registers.  */
+    sim_ppc_spr0_regnum, sim_ppc_spr1_regnum,
+    sim_ppc_spr2_regnum, sim_ppc_spr3_regnum,
+    sim_ppc_spr4_regnum, sim_ppc_spr5_regnum,
+    sim_ppc_spr6_regnum, sim_ppc_spr7_regnum,
+    sim_ppc_spr8_regnum, sim_ppc_spr9_regnum,
+    sim_ppc_spr10_regnum, sim_ppc_spr11_regnum,
+    sim_ppc_spr12_regnum, sim_ppc_spr13_regnum,
+    sim_ppc_spr14_regnum, sim_ppc_spr15_regnum,
+    sim_ppc_spr16_regnum, sim_ppc_spr17_regnum,
+    sim_ppc_spr18_regnum, sim_ppc_spr19_regnum,
+    sim_ppc_spr20_regnum, sim_ppc_spr21_regnum,
+    sim_ppc_spr22_regnum, sim_ppc_spr23_regnum,
+    sim_ppc_spr24_regnum, sim_ppc_spr25_regnum,
+    sim_ppc_spr26_regnum, sim_ppc_spr27_regnum,
+    sim_ppc_spr28_regnum, sim_ppc_spr29_regnum,
+    sim_ppc_spr30_regnum, sim_ppc_spr31_regnum,
+    sim_ppc_spr32_regnum, sim_ppc_spr33_regnum,
+    sim_ppc_spr34_regnum, sim_ppc_spr35_regnum,
+    sim_ppc_spr36_regnum, sim_ppc_spr37_regnum,
+    sim_ppc_spr38_regnum, sim_ppc_spr39_regnum,
+    sim_ppc_spr40_regnum, sim_ppc_spr41_regnum,
+    sim_ppc_spr42_regnum, sim_ppc_spr43_regnum,
+    sim_ppc_spr44_regnum, sim_ppc_spr45_regnum,
+    sim_ppc_spr46_regnum, sim_ppc_spr47_regnum,
+    sim_ppc_spr48_regnum, sim_ppc_spr49_regnum,
+    sim_ppc_spr50_regnum, sim_ppc_spr51_regnum,
+    sim_ppc_spr52_regnum, sim_ppc_spr53_regnum,
+    sim_ppc_spr54_regnum, sim_ppc_spr55_regnum,
+    sim_ppc_spr56_regnum, sim_ppc_spr57_regnum,
+    sim_ppc_spr58_regnum, sim_ppc_spr59_regnum,
+    sim_ppc_spr60_regnum, sim_ppc_spr61_regnum,
+    sim_ppc_spr62_regnum, sim_ppc_spr63_regnum,
+    sim_ppc_spr64_regnum, sim_ppc_spr65_regnum,
+    sim_ppc_spr66_regnum, sim_ppc_spr67_regnum,
+    sim_ppc_spr68_regnum, sim_ppc_spr69_regnum,
+    sim_ppc_spr70_regnum, sim_ppc_spr71_regnum,
+    sim_ppc_spr72_regnum, sim_ppc_spr73_regnum,
+    sim_ppc_spr74_regnum, sim_ppc_spr75_regnum,
+    sim_ppc_spr76_regnum, sim_ppc_spr77_regnum,
+    sim_ppc_spr78_regnum, sim_ppc_spr79_regnum,
+    sim_ppc_spr80_regnum, sim_ppc_spr81_regnum,
+    sim_ppc_spr82_regnum, sim_ppc_spr83_regnum,
+    sim_ppc_spr84_regnum, sim_ppc_spr85_regnum,
+    sim_ppc_spr86_regnum, sim_ppc_spr87_regnum,
+    sim_ppc_spr88_regnum, sim_ppc_spr89_regnum,
+    sim_ppc_spr90_regnum, sim_ppc_spr91_regnum,
+    sim_ppc_spr92_regnum, sim_ppc_spr93_regnum,
+    sim_ppc_spr94_regnum, sim_ppc_spr95_regnum,
+    sim_ppc_spr96_regnum, sim_ppc_spr97_regnum,
+    sim_ppc_spr98_regnum, sim_ppc_spr99_regnum,
+    sim_ppc_spr100_regnum, sim_ppc_spr101_regnum,
+    sim_ppc_spr102_regnum, sim_ppc_spr103_regnum,
+    sim_ppc_spr104_regnum, sim_ppc_spr105_regnum,
+    sim_ppc_spr106_regnum, sim_ppc_spr107_regnum,
+    sim_ppc_spr108_regnum, sim_ppc_spr109_regnum,
+    sim_ppc_spr110_regnum, sim_ppc_spr111_regnum,
+    sim_ppc_spr112_regnum, sim_ppc_spr113_regnum,
+    sim_ppc_spr114_regnum, sim_ppc_spr115_regnum,
+    sim_ppc_spr116_regnum, sim_ppc_spr117_regnum,
+    sim_ppc_spr118_regnum, sim_ppc_spr119_regnum,
+    sim_ppc_spr120_regnum, sim_ppc_spr121_regnum,
+    sim_ppc_spr122_regnum, sim_ppc_spr123_regnum,
+    sim_ppc_spr124_regnum, sim_ppc_spr125_regnum,
+    sim_ppc_spr126_regnum, sim_ppc_spr127_regnum,
+    sim_ppc_spr128_regnum, sim_ppc_spr129_regnum,
+    sim_ppc_spr130_regnum, sim_ppc_spr131_regnum,
+    sim_ppc_spr132_regnum, sim_ppc_spr133_regnum,
+    sim_ppc_spr134_regnum, sim_ppc_spr135_regnum,
+    sim_ppc_spr136_regnum, sim_ppc_spr137_regnum,
+    sim_ppc_spr138_regnum, sim_ppc_spr139_regnum,
+    sim_ppc_spr140_regnum, sim_ppc_spr141_regnum,
+    sim_ppc_spr142_regnum, sim_ppc_spr143_regnum,
+    sim_ppc_spr144_regnum, sim_ppc_spr145_regnum,
+    sim_ppc_spr146_regnum, sim_ppc_spr147_regnum,
+    sim_ppc_spr148_regnum, sim_ppc_spr149_regnum,
+    sim_ppc_spr150_regnum, sim_ppc_spr151_regnum,
+    sim_ppc_spr152_regnum, sim_ppc_spr153_regnum,
+    sim_ppc_spr154_regnum, sim_ppc_spr155_regnum,
+    sim_ppc_spr156_regnum, sim_ppc_spr157_regnum,
+    sim_ppc_spr158_regnum, sim_ppc_spr159_regnum,
+    sim_ppc_spr160_regnum, sim_ppc_spr161_regnum,
+    sim_ppc_spr162_regnum, sim_ppc_spr163_regnum,
+    sim_ppc_spr164_regnum, sim_ppc_spr165_regnum,
+    sim_ppc_spr166_regnum, sim_ppc_spr167_regnum,
+    sim_ppc_spr168_regnum, sim_ppc_spr169_regnum,
+    sim_ppc_spr170_regnum, sim_ppc_spr171_regnum,
+    sim_ppc_spr172_regnum, sim_ppc_spr173_regnum,
+    sim_ppc_spr174_regnum, sim_ppc_spr175_regnum,
+    sim_ppc_spr176_regnum, sim_ppc_spr177_regnum,
+    sim_ppc_spr178_regnum, sim_ppc_spr179_regnum,
+    sim_ppc_spr180_regnum, sim_ppc_spr181_regnum,
+    sim_ppc_spr182_regnum, sim_ppc_spr183_regnum,
+    sim_ppc_spr184_regnum, sim_ppc_spr185_regnum,
+    sim_ppc_spr186_regnum, sim_ppc_spr187_regnum,
+    sim_ppc_spr188_regnum, sim_ppc_spr189_regnum,
+    sim_ppc_spr190_regnum, sim_ppc_spr191_regnum,
+    sim_ppc_spr192_regnum, sim_ppc_spr193_regnum,
+    sim_ppc_spr194_regnum, sim_ppc_spr195_regnum,
+    sim_ppc_spr196_regnum, sim_ppc_spr197_regnum,
+    sim_ppc_spr198_regnum, sim_ppc_spr199_regnum,
+    sim_ppc_spr200_regnum, sim_ppc_spr201_regnum,
+    sim_ppc_spr202_regnum, sim_ppc_spr203_regnum,
+    sim_ppc_spr204_regnum, sim_ppc_spr205_regnum,
+    sim_ppc_spr206_regnum, sim_ppc_spr207_regnum,
+    sim_ppc_spr208_regnum, sim_ppc_spr209_regnum,
+    sim_ppc_spr210_regnum, sim_ppc_spr211_regnum,
+    sim_ppc_spr212_regnum, sim_ppc_spr213_regnum,
+    sim_ppc_spr214_regnum, sim_ppc_spr215_regnum,
+    sim_ppc_spr216_regnum, sim_ppc_spr217_regnum,
+    sim_ppc_spr218_regnum, sim_ppc_spr219_regnum,
+    sim_ppc_spr220_regnum, sim_ppc_spr221_regnum,
+    sim_ppc_spr222_regnum, sim_ppc_spr223_regnum,
+    sim_ppc_spr224_regnum, sim_ppc_spr225_regnum,
+    sim_ppc_spr226_regnum, sim_ppc_spr227_regnum,
+    sim_ppc_spr228_regnum, sim_ppc_spr229_regnum,
+    sim_ppc_spr230_regnum, sim_ppc_spr231_regnum,
+    sim_ppc_spr232_regnum, sim_ppc_spr233_regnum,
+    sim_ppc_spr234_regnum, sim_ppc_spr235_regnum,
+    sim_ppc_spr236_regnum, sim_ppc_spr237_regnum,
+    sim_ppc_spr238_regnum, sim_ppc_spr239_regnum,
+    sim_ppc_spr240_regnum, sim_ppc_spr241_regnum,
+    sim_ppc_spr242_regnum, sim_ppc_spr243_regnum,
+    sim_ppc_spr244_regnum, sim_ppc_spr245_regnum,
+    sim_ppc_spr246_regnum, sim_ppc_spr247_regnum,
+    sim_ppc_spr248_regnum, sim_ppc_spr249_regnum,
+    sim_ppc_spr250_regnum, sim_ppc_spr251_regnum,
+    sim_ppc_spr252_regnum, sim_ppc_spr253_regnum,
+    sim_ppc_spr254_regnum, sim_ppc_spr255_regnum,
+    sim_ppc_spr256_regnum, sim_ppc_spr257_regnum,
+    sim_ppc_spr258_regnum, sim_ppc_spr259_regnum,
+    sim_ppc_spr260_regnum, sim_ppc_spr261_regnum,
+    sim_ppc_spr262_regnum, sim_ppc_spr263_regnum,
+    sim_ppc_spr264_regnum, sim_ppc_spr265_regnum,
+    sim_ppc_spr266_regnum, sim_ppc_spr267_regnum,
+    sim_ppc_spr268_regnum, sim_ppc_spr269_regnum,
+    sim_ppc_spr270_regnum, sim_ppc_spr271_regnum,
+    sim_ppc_spr272_regnum, sim_ppc_spr273_regnum,
+    sim_ppc_spr274_regnum, sim_ppc_spr275_regnum,
+    sim_ppc_spr276_regnum, sim_ppc_spr277_regnum,
+    sim_ppc_spr278_regnum, sim_ppc_spr279_regnum,
+    sim_ppc_spr280_regnum, sim_ppc_spr281_regnum,
+    sim_ppc_spr282_regnum, sim_ppc_spr283_regnum,
+    sim_ppc_spr284_regnum, sim_ppc_spr285_regnum,
+    sim_ppc_spr286_regnum, sim_ppc_spr287_regnum,
+    sim_ppc_spr288_regnum, sim_ppc_spr289_regnum,
+    sim_ppc_spr290_regnum, sim_ppc_spr291_regnum,
+    sim_ppc_spr292_regnum, sim_ppc_spr293_regnum,
+    sim_ppc_spr294_regnum, sim_ppc_spr295_regnum,
+    sim_ppc_spr296_regnum, sim_ppc_spr297_regnum,
+    sim_ppc_spr298_regnum, sim_ppc_spr299_regnum,
+    sim_ppc_spr300_regnum, sim_ppc_spr301_regnum,
+    sim_ppc_spr302_regnum, sim_ppc_spr303_regnum,
+    sim_ppc_spr304_regnum, sim_ppc_spr305_regnum,
+    sim_ppc_spr306_regnum, sim_ppc_spr307_regnum,
+    sim_ppc_spr308_regnum, sim_ppc_spr309_regnum,
+    sim_ppc_spr310_regnum, sim_ppc_spr311_regnum,
+    sim_ppc_spr312_regnum, sim_ppc_spr313_regnum,
+    sim_ppc_spr314_regnum, sim_ppc_spr315_regnum,
+    sim_ppc_spr316_regnum, sim_ppc_spr317_regnum,
+    sim_ppc_spr318_regnum, sim_ppc_spr319_regnum,
+    sim_ppc_spr320_regnum, sim_ppc_spr321_regnum,
+    sim_ppc_spr322_regnum, sim_ppc_spr323_regnum,
+    sim_ppc_spr324_regnum, sim_ppc_spr325_regnum,
+    sim_ppc_spr326_regnum, sim_ppc_spr327_regnum,
+    sim_ppc_spr328_regnum, sim_ppc_spr329_regnum,
+    sim_ppc_spr330_regnum, sim_ppc_spr331_regnum,
+    sim_ppc_spr332_regnum, sim_ppc_spr333_regnum,
+    sim_ppc_spr334_regnum, sim_ppc_spr335_regnum,
+    sim_ppc_spr336_regnum, sim_ppc_spr337_regnum,
+    sim_ppc_spr338_regnum, sim_ppc_spr339_regnum,
+    sim_ppc_spr340_regnum, sim_ppc_spr341_regnum,
+    sim_ppc_spr342_regnum, sim_ppc_spr343_regnum,
+    sim_ppc_spr344_regnum, sim_ppc_spr345_regnum,
+    sim_ppc_spr346_regnum, sim_ppc_spr347_regnum,
+    sim_ppc_spr348_regnum, sim_ppc_spr349_regnum,
+    sim_ppc_spr350_regnum, sim_ppc_spr351_regnum,
+    sim_ppc_spr352_regnum, sim_ppc_spr353_regnum,
+    sim_ppc_spr354_regnum, sim_ppc_spr355_regnum,
+    sim_ppc_spr356_regnum, sim_ppc_spr357_regnum,
+    sim_ppc_spr358_regnum, sim_ppc_spr359_regnum,
+    sim_ppc_spr360_regnum, sim_ppc_spr361_regnum,
+    sim_ppc_spr362_regnum, sim_ppc_spr363_regnum,
+    sim_ppc_spr364_regnum, sim_ppc_spr365_regnum,
+    sim_ppc_spr366_regnum, sim_ppc_spr367_regnum,
+    sim_ppc_spr368_regnum, sim_ppc_spr369_regnum,
+    sim_ppc_spr370_regnum, sim_ppc_spr371_regnum,
+    sim_ppc_spr372_regnum, sim_ppc_spr373_regnum,
+    sim_ppc_spr374_regnum, sim_ppc_spr375_regnum,
+    sim_ppc_spr376_regnum, sim_ppc_spr377_regnum,
+    sim_ppc_spr378_regnum, sim_ppc_spr379_regnum,
+    sim_ppc_spr380_regnum, sim_ppc_spr381_regnum,
+    sim_ppc_spr382_regnum, sim_ppc_spr383_regnum,
+    sim_ppc_spr384_regnum, sim_ppc_spr385_regnum,
+    sim_ppc_spr386_regnum, sim_ppc_spr387_regnum,
+    sim_ppc_spr388_regnum, sim_ppc_spr389_regnum,
+    sim_ppc_spr390_regnum, sim_ppc_spr391_regnum,
+    sim_ppc_spr392_regnum, sim_ppc_spr393_regnum,
+    sim_ppc_spr394_regnum, sim_ppc_spr395_regnum,
+    sim_ppc_spr396_regnum, sim_ppc_spr397_regnum,
+    sim_ppc_spr398_regnum, sim_ppc_spr399_regnum,
+    sim_ppc_spr400_regnum, sim_ppc_spr401_regnum,
+    sim_ppc_spr402_regnum, sim_ppc_spr403_regnum,
+    sim_ppc_spr404_regnum, sim_ppc_spr405_regnum,
+    sim_ppc_spr406_regnum, sim_ppc_spr407_regnum,
+    sim_ppc_spr408_regnum, sim_ppc_spr409_regnum,
+    sim_ppc_spr410_regnum, sim_ppc_spr411_regnum,
+    sim_ppc_spr412_regnum, sim_ppc_spr413_regnum,
+    sim_ppc_spr414_regnum, sim_ppc_spr415_regnum,
+    sim_ppc_spr416_regnum, sim_ppc_spr417_regnum,
+    sim_ppc_spr418_regnum, sim_ppc_spr419_regnum,
+    sim_ppc_spr420_regnum, sim_ppc_spr421_regnum,
+    sim_ppc_spr422_regnum, sim_ppc_spr423_regnum,
+    sim_ppc_spr424_regnum, sim_ppc_spr425_regnum,
+    sim_ppc_spr426_regnum, sim_ppc_spr427_regnum,
+    sim_ppc_spr428_regnum, sim_ppc_spr429_regnum,
+    sim_ppc_spr430_regnum, sim_ppc_spr431_regnum,
+    sim_ppc_spr432_regnum, sim_ppc_spr433_regnum,
+    sim_ppc_spr434_regnum, sim_ppc_spr435_regnum,
+    sim_ppc_spr436_regnum, sim_ppc_spr437_regnum,
+    sim_ppc_spr438_regnum, sim_ppc_spr439_regnum,
+    sim_ppc_spr440_regnum, sim_ppc_spr441_regnum,
+    sim_ppc_spr442_regnum, sim_ppc_spr443_regnum,
+    sim_ppc_spr444_regnum, sim_ppc_spr445_regnum,
+    sim_ppc_spr446_regnum, sim_ppc_spr447_regnum,
+    sim_ppc_spr448_regnum, sim_ppc_spr449_regnum,
+    sim_ppc_spr450_regnum, sim_ppc_spr451_regnum,
+    sim_ppc_spr452_regnum, sim_ppc_spr453_regnum,
+    sim_ppc_spr454_regnum, sim_ppc_spr455_regnum,
+    sim_ppc_spr456_regnum, sim_ppc_spr457_regnum,
+    sim_ppc_spr458_regnum, sim_ppc_spr459_regnum,
+    sim_ppc_spr460_regnum, sim_ppc_spr461_regnum,
+    sim_ppc_spr462_regnum, sim_ppc_spr463_regnum,
+    sim_ppc_spr464_regnum, sim_ppc_spr465_regnum,
+    sim_ppc_spr466_regnum, sim_ppc_spr467_regnum,
+    sim_ppc_spr468_regnum, sim_ppc_spr469_regnum,
+    sim_ppc_spr470_regnum, sim_ppc_spr471_regnum,
+    sim_ppc_spr472_regnum, sim_ppc_spr473_regnum,
+    sim_ppc_spr474_regnum, sim_ppc_spr475_regnum,
+    sim_ppc_spr476_regnum, sim_ppc_spr477_regnum,
+    sim_ppc_spr478_regnum, sim_ppc_spr479_regnum,
+    sim_ppc_spr480_regnum, sim_ppc_spr481_regnum,
+    sim_ppc_spr482_regnum, sim_ppc_spr483_regnum,
+    sim_ppc_spr484_regnum, sim_ppc_spr485_regnum,
+    sim_ppc_spr486_regnum, sim_ppc_spr487_regnum,
+    sim_ppc_spr488_regnum, sim_ppc_spr489_regnum,
+    sim_ppc_spr490_regnum, sim_ppc_spr491_regnum,
+    sim_ppc_spr492_regnum, sim_ppc_spr493_regnum,
+    sim_ppc_spr494_regnum, sim_ppc_spr495_regnum,
+    sim_ppc_spr496_regnum, sim_ppc_spr497_regnum,
+    sim_ppc_spr498_regnum, sim_ppc_spr499_regnum,
+    sim_ppc_spr500_regnum, sim_ppc_spr501_regnum,
+    sim_ppc_spr502_regnum, sim_ppc_spr503_regnum,
+    sim_ppc_spr504_regnum, sim_ppc_spr505_regnum,
+    sim_ppc_spr506_regnum, sim_ppc_spr507_regnum,
+    sim_ppc_spr508_regnum, sim_ppc_spr509_regnum,
+    sim_ppc_spr510_regnum, sim_ppc_spr511_regnum,
+    sim_ppc_spr512_regnum, sim_ppc_spr513_regnum,
+    sim_ppc_spr514_regnum, sim_ppc_spr515_regnum,
+    sim_ppc_spr516_regnum, sim_ppc_spr517_regnum,
+    sim_ppc_spr518_regnum, sim_ppc_spr519_regnum,
+    sim_ppc_spr520_regnum, sim_ppc_spr521_regnum,
+    sim_ppc_spr522_regnum, sim_ppc_spr523_regnum,
+    sim_ppc_spr524_regnum, sim_ppc_spr525_regnum,
+    sim_ppc_spr526_regnum, sim_ppc_spr527_regnum,
+    sim_ppc_spr528_regnum, sim_ppc_spr529_regnum,
+    sim_ppc_spr530_regnum, sim_ppc_spr531_regnum,
+    sim_ppc_spr532_regnum, sim_ppc_spr533_regnum,
+    sim_ppc_spr534_regnum, sim_ppc_spr535_regnum,
+    sim_ppc_spr536_regnum, sim_ppc_spr537_regnum,
+    sim_ppc_spr538_regnum, sim_ppc_spr539_regnum,
+    sim_ppc_spr540_regnum, sim_ppc_spr541_regnum,
+    sim_ppc_spr542_regnum, sim_ppc_spr543_regnum,
+    sim_ppc_spr544_regnum, sim_ppc_spr545_regnum,
+    sim_ppc_spr546_regnum, sim_ppc_spr547_regnum,
+    sim_ppc_spr548_regnum, sim_ppc_spr549_regnum,
+    sim_ppc_spr550_regnum, sim_ppc_spr551_regnum,
+    sim_ppc_spr552_regnum, sim_ppc_spr553_regnum,
+    sim_ppc_spr554_regnum, sim_ppc_spr555_regnum,
+    sim_ppc_spr556_regnum, sim_ppc_spr557_regnum,
+    sim_ppc_spr558_regnum, sim_ppc_spr559_regnum,
+    sim_ppc_spr560_regnum, sim_ppc_spr561_regnum,
+    sim_ppc_spr562_regnum, sim_ppc_spr563_regnum,
+    sim_ppc_spr564_regnum, sim_ppc_spr565_regnum,
+    sim_ppc_spr566_regnum, sim_ppc_spr567_regnum,
+    sim_ppc_spr568_regnum, sim_ppc_spr569_regnum,
+    sim_ppc_spr570_regnum, sim_ppc_spr571_regnum,
+    sim_ppc_spr572_regnum, sim_ppc_spr573_regnum,
+    sim_ppc_spr574_regnum, sim_ppc_spr575_regnum,
+    sim_ppc_spr576_regnum, sim_ppc_spr577_regnum,
+    sim_ppc_spr578_regnum, sim_ppc_spr579_regnum,
+    sim_ppc_spr580_regnum, sim_ppc_spr581_regnum,
+    sim_ppc_spr582_regnum, sim_ppc_spr583_regnum,
+    sim_ppc_spr584_regnum, sim_ppc_spr585_regnum,
+    sim_ppc_spr586_regnum, sim_ppc_spr587_regnum,
+    sim_ppc_spr588_regnum, sim_ppc_spr589_regnum,
+    sim_ppc_spr590_regnum, sim_ppc_spr591_regnum,
+    sim_ppc_spr592_regnum, sim_ppc_spr593_regnum,
+    sim_ppc_spr594_regnum, sim_ppc_spr595_regnum,
+    sim_ppc_spr596_regnum, sim_ppc_spr597_regnum,
+    sim_ppc_spr598_regnum, sim_ppc_spr599_regnum,
+    sim_ppc_spr600_regnum, sim_ppc_spr601_regnum,
+    sim_ppc_spr602_regnum, sim_ppc_spr603_regnum,
+    sim_ppc_spr604_regnum, sim_ppc_spr605_regnum,
+    sim_ppc_spr606_regnum, sim_ppc_spr607_regnum,
+    sim_ppc_spr608_regnum, sim_ppc_spr609_regnum,
+    sim_ppc_spr610_regnum, sim_ppc_spr611_regnum,
+    sim_ppc_spr612_regnum, sim_ppc_spr613_regnum,
+    sim_ppc_spr614_regnum, sim_ppc_spr615_regnum,
+    sim_ppc_spr616_regnum, sim_ppc_spr617_regnum,
+    sim_ppc_spr618_regnum, sim_ppc_spr619_regnum,
+    sim_ppc_spr620_regnum, sim_ppc_spr621_regnum,
+    sim_ppc_spr622_regnum, sim_ppc_spr623_regnum,
+    sim_ppc_spr624_regnum, sim_ppc_spr625_regnum,
+    sim_ppc_spr626_regnum, sim_ppc_spr627_regnum,
+    sim_ppc_spr628_regnum, sim_ppc_spr629_regnum,
+    sim_ppc_spr630_regnum, sim_ppc_spr631_regnum,
+    sim_ppc_spr632_regnum, sim_ppc_spr633_regnum,
+    sim_ppc_spr634_regnum, sim_ppc_spr635_regnum,
+    sim_ppc_spr636_regnum, sim_ppc_spr637_regnum,
+    sim_ppc_spr638_regnum, sim_ppc_spr639_regnum,
+    sim_ppc_spr640_regnum, sim_ppc_spr641_regnum,
+    sim_ppc_spr642_regnum, sim_ppc_spr643_regnum,
+    sim_ppc_spr644_regnum, sim_ppc_spr645_regnum,
+    sim_ppc_spr646_regnum, sim_ppc_spr647_regnum,
+    sim_ppc_spr648_regnum, sim_ppc_spr649_regnum,
+    sim_ppc_spr650_regnum, sim_ppc_spr651_regnum,
+    sim_ppc_spr652_regnum, sim_ppc_spr653_regnum,
+    sim_ppc_spr654_regnum, sim_ppc_spr655_regnum,
+    sim_ppc_spr656_regnum, sim_ppc_spr657_regnum,
+    sim_ppc_spr658_regnum, sim_ppc_spr659_regnum,
+    sim_ppc_spr660_regnum, sim_ppc_spr661_regnum,
+    sim_ppc_spr662_regnum, sim_ppc_spr663_regnum,
+    sim_ppc_spr664_regnum, sim_ppc_spr665_regnum,
+    sim_ppc_spr666_regnum, sim_ppc_spr667_regnum,
+    sim_ppc_spr668_regnum, sim_ppc_spr669_regnum,
+    sim_ppc_spr670_regnum, sim_ppc_spr671_regnum,
+    sim_ppc_spr672_regnum, sim_ppc_spr673_regnum,
+    sim_ppc_spr674_regnum, sim_ppc_spr675_regnum,
+    sim_ppc_spr676_regnum, sim_ppc_spr677_regnum,
+    sim_ppc_spr678_regnum, sim_ppc_spr679_regnum,
+    sim_ppc_spr680_regnum, sim_ppc_spr681_regnum,
+    sim_ppc_spr682_regnum, sim_ppc_spr683_regnum,
+    sim_ppc_spr684_regnum, sim_ppc_spr685_regnum,
+    sim_ppc_spr686_regnum, sim_ppc_spr687_regnum,
+    sim_ppc_spr688_regnum, sim_ppc_spr689_regnum,
+    sim_ppc_spr690_regnum, sim_ppc_spr691_regnum,
+    sim_ppc_spr692_regnum, sim_ppc_spr693_regnum,
+    sim_ppc_spr694_regnum, sim_ppc_spr695_regnum,
+    sim_ppc_spr696_regnum, sim_ppc_spr697_regnum,
+    sim_ppc_spr698_regnum, sim_ppc_spr699_regnum,
+    sim_ppc_spr700_regnum, sim_ppc_spr701_regnum,
+    sim_ppc_spr702_regnum, sim_ppc_spr703_regnum,
+    sim_ppc_spr704_regnum, sim_ppc_spr705_regnum,
+    sim_ppc_spr706_regnum, sim_ppc_spr707_regnum,
+    sim_ppc_spr708_regnum, sim_ppc_spr709_regnum,
+    sim_ppc_spr710_regnum, sim_ppc_spr711_regnum,
+    sim_ppc_spr712_regnum, sim_ppc_spr713_regnum,
+    sim_ppc_spr714_regnum, sim_ppc_spr715_regnum,
+    sim_ppc_spr716_regnum, sim_ppc_spr717_regnum,
+    sim_ppc_spr718_regnum, sim_ppc_spr719_regnum,
+    sim_ppc_spr720_regnum, sim_ppc_spr721_regnum,
+    sim_ppc_spr722_regnum, sim_ppc_spr723_regnum,
+    sim_ppc_spr724_regnum, sim_ppc_spr725_regnum,
+    sim_ppc_spr726_regnum, sim_ppc_spr727_regnum,
+    sim_ppc_spr728_regnum, sim_ppc_spr729_regnum,
+    sim_ppc_spr730_regnum, sim_ppc_spr731_regnum,
+    sim_ppc_spr732_regnum, sim_ppc_spr733_regnum,
+    sim_ppc_spr734_regnum, sim_ppc_spr735_regnum,
+    sim_ppc_spr736_regnum, sim_ppc_spr737_regnum,
+    sim_ppc_spr738_regnum, sim_ppc_spr739_regnum,
+    sim_ppc_spr740_regnum, sim_ppc_spr741_regnum,
+    sim_ppc_spr742_regnum, sim_ppc_spr743_regnum,
+    sim_ppc_spr744_regnum, sim_ppc_spr745_regnum,
+    sim_ppc_spr746_regnum, sim_ppc_spr747_regnum,
+    sim_ppc_spr748_regnum, sim_ppc_spr749_regnum,
+    sim_ppc_spr750_regnum, sim_ppc_spr751_regnum,
+    sim_ppc_spr752_regnum, sim_ppc_spr753_regnum,
+    sim_ppc_spr754_regnum, sim_ppc_spr755_regnum,
+    sim_ppc_spr756_regnum, sim_ppc_spr757_regnum,
+    sim_ppc_spr758_regnum, sim_ppc_spr759_regnum,
+    sim_ppc_spr760_regnum, sim_ppc_spr761_regnum,
+    sim_ppc_spr762_regnum, sim_ppc_spr763_regnum,
+    sim_ppc_spr764_regnum, sim_ppc_spr765_regnum,
+    sim_ppc_spr766_regnum, sim_ppc_spr767_regnum,
+    sim_ppc_spr768_regnum, sim_ppc_spr769_regnum,
+    sim_ppc_spr770_regnum, sim_ppc_spr771_regnum,
+    sim_ppc_spr772_regnum, sim_ppc_spr773_regnum,
+    sim_ppc_spr774_regnum, sim_ppc_spr775_regnum,
+    sim_ppc_spr776_regnum, sim_ppc_spr777_regnum,
+    sim_ppc_spr778_regnum, sim_ppc_spr779_regnum,
+    sim_ppc_spr780_regnum, sim_ppc_spr781_regnum,
+    sim_ppc_spr782_regnum, sim_ppc_spr783_regnum,
+    sim_ppc_spr784_regnum, sim_ppc_spr785_regnum,
+    sim_ppc_spr786_regnum, sim_ppc_spr787_regnum,
+    sim_ppc_spr788_regnum, sim_ppc_spr789_regnum,
+    sim_ppc_spr790_regnum, sim_ppc_spr791_regnum,
+    sim_ppc_spr792_regnum, sim_ppc_spr793_regnum,
+    sim_ppc_spr794_regnum, sim_ppc_spr795_regnum,
+    sim_ppc_spr796_regnum, sim_ppc_spr797_regnum,
+    sim_ppc_spr798_regnum, sim_ppc_spr799_regnum,
+    sim_ppc_spr800_regnum, sim_ppc_spr801_regnum,
+    sim_ppc_spr802_regnum, sim_ppc_spr803_regnum,
+    sim_ppc_spr804_regnum, sim_ppc_spr805_regnum,
+    sim_ppc_spr806_regnum, sim_ppc_spr807_regnum,
+    sim_ppc_spr808_regnum, sim_ppc_spr809_regnum,
+    sim_ppc_spr810_regnum, sim_ppc_spr811_regnum,
+    sim_ppc_spr812_regnum, sim_ppc_spr813_regnum,
+    sim_ppc_spr814_regnum, sim_ppc_spr815_regnum,
+    sim_ppc_spr816_regnum, sim_ppc_spr817_regnum,
+    sim_ppc_spr818_regnum, sim_ppc_spr819_regnum,
+    sim_ppc_spr820_regnum, sim_ppc_spr821_regnum,
+    sim_ppc_spr822_regnum, sim_ppc_spr823_regnum,
+    sim_ppc_spr824_regnum, sim_ppc_spr825_regnum,
+    sim_ppc_spr826_regnum, sim_ppc_spr827_regnum,
+    sim_ppc_spr828_regnum, sim_ppc_spr829_regnum,
+    sim_ppc_spr830_regnum, sim_ppc_spr831_regnum,
+    sim_ppc_spr832_regnum, sim_ppc_spr833_regnum,
+    sim_ppc_spr834_regnum, sim_ppc_spr835_regnum,
+    sim_ppc_spr836_regnum, sim_ppc_spr837_regnum,
+    sim_ppc_spr838_regnum, sim_ppc_spr839_regnum,
+    sim_ppc_spr840_regnum, sim_ppc_spr841_regnum,
+    sim_ppc_spr842_regnum, sim_ppc_spr843_regnum,
+    sim_ppc_spr844_regnum, sim_ppc_spr845_regnum,
+    sim_ppc_spr846_regnum, sim_ppc_spr847_regnum,
+    sim_ppc_spr848_regnum, sim_ppc_spr849_regnum,
+    sim_ppc_spr850_regnum, sim_ppc_spr851_regnum,
+    sim_ppc_spr852_regnum, sim_ppc_spr853_regnum,
+    sim_ppc_spr854_regnum, sim_ppc_spr855_regnum,
+    sim_ppc_spr856_regnum, sim_ppc_spr857_regnum,
+    sim_ppc_spr858_regnum, sim_ppc_spr859_regnum,
+    sim_ppc_spr860_regnum, sim_ppc_spr861_regnum,
+    sim_ppc_spr862_regnum, sim_ppc_spr863_regnum,
+    sim_ppc_spr864_regnum, sim_ppc_spr865_regnum,
+    sim_ppc_spr866_regnum, sim_ppc_spr867_regnum,
+    sim_ppc_spr868_regnum, sim_ppc_spr869_regnum,
+    sim_ppc_spr870_regnum, sim_ppc_spr871_regnum,
+    sim_ppc_spr872_regnum, sim_ppc_spr873_regnum,
+    sim_ppc_spr874_regnum, sim_ppc_spr875_regnum,
+    sim_ppc_spr876_regnum, sim_ppc_spr877_regnum,
+    sim_ppc_spr878_regnum, sim_ppc_spr879_regnum,
+    sim_ppc_spr880_regnum, sim_ppc_spr881_regnum,
+    sim_ppc_spr882_regnum, sim_ppc_spr883_regnum,
+    sim_ppc_spr884_regnum, sim_ppc_spr885_regnum,
+    sim_ppc_spr886_regnum, sim_ppc_spr887_regnum,
+    sim_ppc_spr888_regnum, sim_ppc_spr889_regnum,
+    sim_ppc_spr890_regnum, sim_ppc_spr891_regnum,
+    sim_ppc_spr892_regnum, sim_ppc_spr893_regnum,
+    sim_ppc_spr894_regnum, sim_ppc_spr895_regnum,
+    sim_ppc_spr896_regnum, sim_ppc_spr897_regnum,
+    sim_ppc_spr898_regnum, sim_ppc_spr899_regnum,
+    sim_ppc_spr900_regnum, sim_ppc_spr901_regnum,
+    sim_ppc_spr902_regnum, sim_ppc_spr903_regnum,
+    sim_ppc_spr904_regnum, sim_ppc_spr905_regnum,
+    sim_ppc_spr906_regnum, sim_ppc_spr907_regnum,
+    sim_ppc_spr908_regnum, sim_ppc_spr909_regnum,
+    sim_ppc_spr910_regnum, sim_ppc_spr911_regnum,
+    sim_ppc_spr912_regnum, sim_ppc_spr913_regnum,
+    sim_ppc_spr914_regnum, sim_ppc_spr915_regnum,
+    sim_ppc_spr916_regnum, sim_ppc_spr917_regnum,
+    sim_ppc_spr918_regnum, sim_ppc_spr919_regnum,
+    sim_ppc_spr920_regnum, sim_ppc_spr921_regnum,
+    sim_ppc_spr922_regnum, sim_ppc_spr923_regnum,
+    sim_ppc_spr924_regnum, sim_ppc_spr925_regnum,
+    sim_ppc_spr926_regnum, sim_ppc_spr927_regnum,
+    sim_ppc_spr928_regnum, sim_ppc_spr929_regnum,
+    sim_ppc_spr930_regnum, sim_ppc_spr931_regnum,
+    sim_ppc_spr932_regnum, sim_ppc_spr933_regnum,
+    sim_ppc_spr934_regnum, sim_ppc_spr935_regnum,
+    sim_ppc_spr936_regnum, sim_ppc_spr937_regnum,
+    sim_ppc_spr938_regnum, sim_ppc_spr939_regnum,
+    sim_ppc_spr940_regnum, sim_ppc_spr941_regnum,
+    sim_ppc_spr942_regnum, sim_ppc_spr943_regnum,
+    sim_ppc_spr944_regnum, sim_ppc_spr945_regnum,
+    sim_ppc_spr946_regnum, sim_ppc_spr947_regnum,
+    sim_ppc_spr948_regnum, sim_ppc_spr949_regnum,
+    sim_ppc_spr950_regnum, sim_ppc_spr951_regnum,
+    sim_ppc_spr952_regnum, sim_ppc_spr953_regnum,
+    sim_ppc_spr954_regnum, sim_ppc_spr955_regnum,
+    sim_ppc_spr956_regnum, sim_ppc_spr957_regnum,
+    sim_ppc_spr958_regnum, sim_ppc_spr959_regnum,
+    sim_ppc_spr960_regnum, sim_ppc_spr961_regnum,
+    sim_ppc_spr962_regnum, sim_ppc_spr963_regnum,
+    sim_ppc_spr964_regnum, sim_ppc_spr965_regnum,
+    sim_ppc_spr966_regnum, sim_ppc_spr967_regnum,
+    sim_ppc_spr968_regnum, sim_ppc_spr969_regnum,
+    sim_ppc_spr970_regnum, sim_ppc_spr971_regnum,
+    sim_ppc_spr972_regnum, sim_ppc_spr973_regnum,
+    sim_ppc_spr974_regnum, sim_ppc_spr975_regnum,
+    sim_ppc_spr976_regnum, sim_ppc_spr977_regnum,
+    sim_ppc_spr978_regnum, sim_ppc_spr979_regnum,
+    sim_ppc_spr980_regnum, sim_ppc_spr981_regnum,
+    sim_ppc_spr982_regnum, sim_ppc_spr983_regnum,
+    sim_ppc_spr984_regnum, sim_ppc_spr985_regnum,
+    sim_ppc_spr986_regnum, sim_ppc_spr987_regnum,
+    sim_ppc_spr988_regnum, sim_ppc_spr989_regnum,
+    sim_ppc_spr990_regnum, sim_ppc_spr991_regnum,
+    sim_ppc_spr992_regnum, sim_ppc_spr993_regnum,
+    sim_ppc_spr994_regnum, sim_ppc_spr995_regnum,
+    sim_ppc_spr996_regnum, sim_ppc_spr997_regnum,
+    sim_ppc_spr998_regnum, sim_ppc_spr999_regnum,
+    sim_ppc_spr1000_regnum, sim_ppc_spr1001_regnum,
+    sim_ppc_spr1002_regnum, sim_ppc_spr1003_regnum,
+    sim_ppc_spr1004_regnum, sim_ppc_spr1005_regnum,
+    sim_ppc_spr1006_regnum, sim_ppc_spr1007_regnum,
+    sim_ppc_spr1008_regnum, sim_ppc_spr1009_regnum,
+    sim_ppc_spr1010_regnum, sim_ppc_spr1011_regnum,
+    sim_ppc_spr1012_regnum, sim_ppc_spr1013_regnum,
+    sim_ppc_spr1014_regnum, sim_ppc_spr1015_regnum,
+    sim_ppc_spr1016_regnum, sim_ppc_spr1017_regnum,
+    sim_ppc_spr1018_regnum, sim_ppc_spr1019_regnum,
+    sim_ppc_spr1020_regnum, sim_ppc_spr1021_regnum,
+    sim_ppc_spr1022_regnum, sim_ppc_spr1023_regnum
+  };
+
+
+/* Sizes of various register sets.  */
+enum
+  {
+    sim_ppc_num_gprs = 32,
+    sim_ppc_num_fprs = 32,
+    sim_ppc_num_vrs = 32,
+    sim_ppc_num_srs = 16,
+    sim_ppc_num_sprs = 1024,
+  };
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SIM_PPC_H */
diff --git a/include/opcode/crx.h b/include/opcode/crx.h
new file mode 100644 (file)
index 0000000..1e0d573
--- /dev/null
@@ -0,0 +1,395 @@
+/* crx.h -- Header file for CRX opcode and register tables.
+   Copyright 2004 Free Software Foundation, Inc.
+   Contributed by Tomer Levi, NSC, Israel.
+   Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
+   Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
+
+   This file is part of GAS, GDB and the GNU binutils.
+
+   GAS, GDB, and GNU binutils 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, or (at your
+   option) any later version.
+
+   GAS, GDB, and GNU binutils are distributed in the hope that they 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 _CRX_H_
+#define _CRX_H_
+
+/* CRX core/debug Registers :
+   The enums are used as indices to CRX registers table (crx_regtab).
+   Therefore, order MUST be preserved.  */
+
+typedef enum
+  {
+    /* 32-bit general purpose registers.  */
+    r0, r1, r2, r3, r4, r5, r6, r7, r8, r9,
+    r10, r11, r12, r13, r14, r15, ra, sp,
+    /* 32-bit user registers.  */
+    u0, u1, u2, u3, u4, u5, u6, u7, u8, u9,
+    u10, u11, u12, u13, u14, u15, ura, usp,
+    /* hi and lo registers.  */
+    hi, lo,
+    /* hi and lo user registers.  */
+    uhi, ulo,
+    /* Processor Status Register.  */
+    psr,
+    /* Configuration Register.  */
+    cfg,
+    /* Coprocessor Configuration Register.  */
+    cpcfg,
+    /* Cashe Configuration Register.  */
+    ccfg,
+    /* Interrupt Base Register.  */
+    intbase,
+    /* Interrupt Stack Pointer Register.  */
+    isp,
+    /* Coprocessor Enable Register.  */
+    cen,
+    /* Program Counter Register.  */
+    pc,
+    /* Not a register.  */
+    nullregister,
+    MAX_REG
+  }
+reg;
+
+/* CRX Coprocessor registers and special registers :
+   The enums are used as indices to CRX coprocessor registers table
+   (crx_copregtab). Therefore, order MUST be preserved.  */
+
+typedef enum
+  {
+    /* Coprocessor registers.  */
+    c0 = MAX_REG, c1, c2, c3, c4, c5, c6, c7, c8,
+    c9, c10, c11, c12, c13, c14, c15,
+    /* Coprocessor special registers.  */
+    cs0, cs1 ,cs2, cs3, cs4, cs5, cs6, cs7, cs8,
+    cs9, cs10, cs11, cs12, cs13, cs14, cs15,
+    /* Not a Coprocessor register.  */
+    nullcopregister,
+    MAX_COPREG
+  }
+copreg;
+
+/* CRX Register types. */
+
+typedef enum
+  {
+    CRX_PC_REGTYPE,   /*  pc type */
+    CRX_R_REGTYPE,    /*  r<N>   */
+    CRX_U_REGTYPE,    /*  u<N>   */
+    CRX_C_REGTYPE,    /*  c<N>   */
+    CRX_CS_REGTYPE,   /*  cs<N>          */
+    CRX_MTPR_REGTYPE, /*  mtpr   */
+    CRX_CFG_REGTYPE   /*  *hi|lo, *cfg, psr */
+  }
+reg_type;
+
+/* CRX argument types :
+   The argument types correspond to instructions operands
+
+   Argument types :
+   r - register
+   c - constant
+   d - displacement
+   ic - immediate
+   icr - index register
+   rbase - register base
+   s - star ('*')
+   copr - coprocessor register
+   copsr - coprocessor special register.  */
+
+typedef enum
+  {
+    arg_r, arg_c, arg_cr, arg_dc, arg_dcr, arg_sc,
+    arg_ic, arg_icr, arg_rbase, arg_copr, arg_copsr,
+    /* Not an argument.  */
+    nullargs
+  }
+argtype;
+
+/* CRX operand types :
+   The operand types correspond to instructions operands
+
+   Operand Types :
+   cst4 - 4-bit encoded constant
+   iN - N-bit immediate field
+   d, dispsN - N-bit immediate signed displacement
+   dispuN - N-bit immediate unsigned displacement
+   absN - N-bit absolute address
+   rbase - 4-bit genaral-purpose register specifier
+   regr - 4-bit genaral-purpose register specifier
+   regr8 - 8-bit register address space
+   copregr - coprocessor register
+   copsregr - coprocessor special register
+   scl2 - 2-bit scaling factor for memory index
+   ridx - register index.  */
+
+typedef enum
+  {
+    dummy, cst4, disps9,
+    i3, i4, i5, i8, i12, i16, i32,
+    d5, d9, d17, d25, d33,
+    abs16, abs32,
+    rbase, rbase_cst4,
+    rbase_dispu8, rbase_dispu12, rbase_dispu16, rbase_dispu28, rbase_dispu32,
+    rbase_ridx_scl2_dispu6, rbase_ridx_scl2_dispu22,
+    regr, regr8, copregr,copregr8,copsregr,
+    /* Not an operand.  */
+    nulloperand,
+    /* Maximum supported operand.  */
+    MAX_OPRD
+  }
+operand_type;
+
+/* CRX instruction types.  */
+
+#define ARITH_INS         1
+#define LD_STOR_INS       2
+#define BRANCH_INS        3
+#define ARITH_BYTE_INS    4
+#define CMPBR_INS         5
+#define SHIFT_INS         6
+#define BRANCH_NEQ_INS    7
+#define LD_STOR_INS_INC   8
+#define STOR_IMM_INS     9
+#define CSTBIT_INS       10
+#define SYS_INS                 11
+#define JMP_INS                 12
+#define MUL_INS                 13
+#define DIV_INS                 14
+#define COP_BRANCH_INS   15
+#define COP_REG_INS      16
+#define DCR_BRANCH_INS   17
+#define MMC_INS          18
+#define MMU_INS          19
+
+/* Maximum value supported for instruction types.  */
+#define CRX_INS_MAX    (1 << 5)
+/* Mask to record an instruction type.  */
+#define CRX_INS_MASK   (CRX_INS_MAX - 1)
+/* Return instruction type, given instruction's attributes.  */
+#define CRX_INS_TYPE(attr) ((attr) & CRX_INS_MASK)
+
+/* Indicates whether this instruction has a register list as parameter.  */
+#define REG_LIST       CRX_INS_MAX
+/* The operands in binary and assembly are placed in reverse order.
+   load - (REVERSE_MATCH)/store - (! REVERSE_MATCH).  */
+#define REVERSE_MATCH  (REG_LIST << 1)
+
+/* Kind of displacement map used DISPU[BWD]4.  */
+#define DISPUB4               (REVERSE_MATCH << 1)
+#define DISPUW4               (DISPUB4 << 1)
+#define DISPUD4               (DISPUW4 << 1)
+#define CST4MAP               (DISPUB4 | DISPUW4 | DISPUD4)
+
+/* Printing formats, where the instruction prefix isn't consecutive.  */
+#define FMT_1         (DISPUD4 << 1) /* 0xF0F00000 */
+#define FMT_2         (FMT_1 << 1)   /* 0xFFF0FF00 */
+#define FMT_3         (FMT_2 << 1)   /* 0xFFF00F00 */
+#define FMT_4         (FMT_3 << 1)   /* 0xFFF0F000 */
+#define FMT_5         (FMT_4 << 1)   /* 0xFFF0FFF0 */
+#define FMT_CRX               (FMT_1 | FMT_2 | FMT_3 | FMT_4 | FMT_5)
+
+#define RELAXABLE      (FMT_5 << 1)
+
+/* Maximum operands per instruction.  */
+#define MAX_OPERANDS     5
+/* Maximum words per instruction.  */
+#define MAX_WORDS        3
+/* Maximum register name length. */
+#define MAX_REGNAME_LEN          10
+/* Maximum instruction length. */
+#define MAX_INST_LEN     256
+
+/* Single operand description.  */
+
+typedef struct
+  {
+    /* Operand type.  */
+    operand_type op_type;
+    /* Operand location within the opcode.  */
+    unsigned int shift;
+  }
+operand_desc;
+
+/* Instruction data structure used in instruction table.  */
+
+typedef struct
+  {
+    /* Name.  */
+    const char *mnemonic;
+    /* Size (in words).  */
+    unsigned int size;
+    /* Constant prefix (matched by the disassembler).  */
+    unsigned long match;
+    /* Match size (in bits).  */
+    int match_bits;
+    /* Attributes.  */
+    unsigned int flags;
+    /* Operands (always last, so unreferenced operands are initialized).  */
+    operand_desc operands[MAX_OPERANDS];
+  }
+inst;
+
+/* Data structure for a single instruction's arguments (Operands).  */
+
+typedef struct
+  {
+    /* Register or base register.  */
+    reg r;
+    /* Index register.  */
+    reg i_r;
+    /* Coprocessor register.  */
+    copreg cr;
+    /* Constant/immediate/absolute value.  */
+    unsigned long int constant;
+    /* Scaled index mode.  */
+    unsigned int scale;
+    /* Argument type.  */
+    argtype type;
+    /* Size of the argument (in bits) required to represent.  */
+    int size;
+    /* Indicates whether a constant is positive or negative.  */
+    int signflag;
+  }
+argument;
+
+/* Internal structure to hold the various entities
+   corresponding to the current assembling instruction.  */
+
+typedef struct
+  {
+    /* Number of arguments.  */
+    int nargs;
+    /* The argument data structure for storing args (operands).  */
+    argument arg[MAX_OPERANDS];
+/* The following fields are required only by CRX-assembler.  */
+#ifdef TC_CRX
+    /* Expression used for setting the fixups (if any).  */
+    expressionS exp;
+    bfd_reloc_code_real_type rtype;
+#endif /* TC_CRX */
+    /* Instruction size (in bytes).  */
+    int size;
+  }
+ins;
+
+/* Structure to hold information about predefined operands.  */
+
+typedef struct
+  {
+    /* Size (in bits).  */
+    unsigned int bit_size;
+    /* Argument type.  */
+    argtype arg_type;
+  }
+operand_entry;
+
+/* Structure to hold trap handler information.  */
+
+typedef struct
+  {
+    /* Trap name.  */
+    char *name;
+    /* Index in dispatch table.  */
+    unsigned int entry;
+  }
+trap_entry;
+
+/* Structure to hold information about predefined registers.  */
+
+typedef struct
+  {
+    /* Name (string representation).  */
+    char *name;
+    /* Value (enum representation).  */
+    union
+    {
+      /* Register.  */
+      reg reg_val;
+      /* Coprocessor register.  */
+      copreg copreg_val;
+    } value;
+    /* Register image.  */
+    int image;
+    /* Register type.  */
+    reg_type type;
+  }
+reg_entry;
+
+/* Structure to hold a cst4 operand mapping.  */
+
+typedef struct
+  {
+    /* The binary value which is written to the object file.  */
+    int binary;
+    /* The value which is mapped.  */
+    int value;
+  }
+cst4_entry;
+
+/* CRX opcode table.  */
+extern const inst crx_instruction[];
+extern const int crx_num_opcodes;
+#define NUMOPCODES crx_num_opcodes
+
+/* CRX operands table.  */
+extern const operand_entry crx_optab[];
+
+/* CRX registers table.  */
+extern const reg_entry crx_regtab[];
+extern const int crx_num_regs;
+#define NUMREGS crx_num_regs
+
+/* CRX coprocessor registers table.  */
+extern const reg_entry crx_copregtab[];
+extern const int crx_num_copregs;
+#define NUMCOPREGS crx_num_copregs
+
+/* CRX trap/interrupt table.  */
+extern const trap_entry crx_traps[];
+extern const int crx_num_traps;
+#define NUMTRAPS crx_num_traps
+
+/* cst4 operand mapping.  */
+extern const cst4_entry cst4_map[];
+extern const int cst4_maps;
+
+/* Current instruction we're assembling.  */
+extern const inst *instruction;
+
+/* A macro for representing the instruction "constant" opcode, that is,
+   the FIXED part of the instruction. The "constant" opcode is represented
+   as a 32-bit unsigned long, where OPC is expanded (by a left SHIFT)
+   over that range.  */
+#define BIN(OPC,SHIFT) (OPC << SHIFT)
+
+/* Is the current instruction type is TYPE ?  */
+#define IS_INSN_TYPE(TYPE)           \
+  (CRX_INS_TYPE(instruction->flags) == TYPE)
+
+/* Is the current instruction mnemonic is MNEMONIC ?  */
+#define IS_INSN_MNEMONIC(MNEMONIC)    \
+  (strcmp(instruction->mnemonic,MNEMONIC) == 0)
+
+/* Does the current instruction has register list ?  */
+#define INST_HAS_REG_LIST            \
+  (instruction->flags & REG_LIST)
+
+/* Long long type handling.  */
+/* Replace all appearances of 'long long int' with LONGLONG.  */
+typedef long long int LONGLONG;
+typedef unsigned long long ULONGLONG;
+/* A mask for the upper 31 bits of a 64 bits type.  */
+#define UPPER31_MASK   0xFFFFFFFE00000000LL
+
+#endif /* _CRX_H_ */
diff --git a/opcodes/crx-dis.c b/opcodes/crx-dis.c
new file mode 100644 (file)
index 0000000..5796a2e
--- /dev/null
@@ -0,0 +1,700 @@
+/* Disassembler code for CRX.
+   Copyright 2004 Free Software Foundation, Inc.
+   Contributed by Tomer Levi, NSC, Israel.
+   Written by Tomer Levi.
+
+   This file is part of the GNU binutils and GDB, the GNU debugger.
+
+   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, 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.  */
+
+#include "dis-asm.h"
+#include "sysdep.h"
+#include "opcode/crx.h"
+
+/* String to print when opcode was not matched.  */
+#define ILLEGAL        "illegal"
+  /* Escape to 16-bit immediate.  */
+#define ESCAPE_16_BIT  0xE
+
+/* Extract 'n_bits' from 'a' starting from offset 'offs'.  */
+#define EXTRACT(a, offs, n_bits)           \
+  (n_bits == 32 ? (((a) >> (offs)) & ~0L)   \
+  : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
+
+/* Set Bit Mask - a mask to set all bits starting from offset 'offs'.  */
+#define SBM(offs)  ((((1 << (32 - offs)) -1) << (offs)))
+
+typedef unsigned long dwordU;
+typedef unsigned short wordU;
+
+typedef struct
+{
+  dwordU val;
+  int nbits;
+} parameter;
+
+/* Structure to hold valid 'cinv' instruction options.  */
+
+typedef struct
+  {
+    /* Cinv printed string.  */
+    char *str;
+    /* Value corresponding to the string.  */
+    unsigned int value;
+  }
+cinv_entry;
+
+/* CRX 'cinv' options.  */
+const cinv_entry crx_cinvs[] =
+{
+  {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4},
+  {"[d,u]", 5}, {"[d,i]", 6}, {"[d,i,u]", 7}
+};
+
+/* Number of valid 'cinv' instruction options.  */
+int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0]));
+/* Current opcode table entry we're disassembling.  */
+const inst *instruction;
+/* Current instruction we're disassembling.  */
+ins currInsn;
+/* The current instruction is read into 3 consecutive words.  */
+wordU words[3];
+/* Contains all words in appropriate order.  */
+ULONGLONG allWords;
+/* Holds the current processed argument number.  */
+int processing_argument_number;
+/* Nonzero means a CST4 instruction.  */
+int cst4flag;
+/* Nonzero means the instruction's original size is
+   incremented (escape sequence is used).  */
+int size_changed;
+
+static int get_number_of_operands (void);
+static argtype getargtype     (operand_type);
+static int getbits           (operand_type);
+static char *getregname              (reg);
+static char *getcopregname    (copreg, reg_type);
+static char * getprocregname  (int);
+static char *gettrapstring    (unsigned);
+static char *getcinvstring    (unsigned);
+static void getregliststring  (int, char *, int);
+static wordU get_word_at_PC   (bfd_vma, struct disassemble_info *);
+static void get_words_at_PC   (bfd_vma, struct disassemble_info *);
+static unsigned long build_mask (void);
+static int powerof2          (int);
+static int match_opcode              (void);
+static void make_instruction  (void);
+static void print_arguments   (ins *, struct disassemble_info *);
+static void print_arg        (argument *, struct disassemble_info *);
+
+/* Retrieve the number of operands for the current assembled instruction.  */
+
+static int
+get_number_of_operands (void)
+{
+  int i;
+
+  for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
+    ;
+
+  return i;
+}
+
+/* Return the bit size for a given operand.  */
+
+static int
+getbits (operand_type op)
+{
+  if (op < MAX_OPRD)
+    return crx_optab[op].bit_size;
+  else
+    return 0;
+}
+
+/* Return the argument type of a given operand.  */
+
+static argtype
+getargtype (operand_type op)
+{
+  if (op < MAX_OPRD)
+    return crx_optab[op].arg_type;
+  else
+    return nullargs;
+}
+
+/* Given the trap index in dispatch table, return its name.
+   This routine is used when disassembling the 'excp' instruction.  */
+
+static char *
+gettrapstring (unsigned int index)
+{
+  const trap_entry *trap;
+
+  for (trap = crx_traps; trap < crx_traps + NUMTRAPS; trap++)
+    if (trap->entry == index)
+      return trap->name;
+
+  return ILLEGAL;
+}
+
+/* Given a 'cinv' instruction constant operand, return its corresponding string.
+   This routine is used when disassembling the 'cinv' instruction.  */
+
+static char *
+getcinvstring (unsigned int num)
+{
+  const cinv_entry *cinv;
+
+  for (cinv = crx_cinvs; cinv < (crx_cinvs + NUMCINVS); cinv++)
+    if (cinv->value == num)
+      return cinv->str;
+
+  return ILLEGAL;
+}
+
+/* Given a register enum value, retrieve its name.  */
+
+char *
+getregname (reg r)
+{
+  const reg_entry *reg = &crx_regtab[r];
+
+  if (reg->type != CRX_R_REGTYPE)
+    return ILLEGAL;
+  else
+    return reg->name;
+}
+
+/* Given a coprocessor register enum value, retrieve its name.  */
+
+char *
+getcopregname (copreg r, reg_type type)
+{
+  const reg_entry *reg;
+
+  if (type == CRX_C_REGTYPE)
+    reg = &crx_copregtab[r];
+  else if (type == CRX_CS_REGTYPE)
+    reg = &crx_copregtab[r+(cs0-c0)];
+  else
+    return ILLEGAL;
+
+  return reg->name;
+}
+
+
+/* Getting a processor register name.  */
+
+static char *
+getprocregname (int index)
+{
+  const reg_entry *r;
+
+  for (r = crx_regtab; r < crx_regtab + NUMREGS; r++)
+    if (r->image == index)
+      return r->name;
+
+  return "ILLEGAL REGISTER";
+}
+
+/* Get the power of two for a given integer.  */
+
+static int
+powerof2 (int x)
+{
+  int product, i;
+
+  for (i = 0, product = 1; i < x; i++)
+    product *= 2;
+
+  return product;
+}
+
+/* Transform a register bit mask to a register list.  */
+
+void
+getregliststring (int trap, char *string, int core_cop)
+{
+  char temp_string[5];
+  int i;
+
+  string[0] = '{';
+  string[1] = '\0';
+
+  for (i = 0; i < 16; i++)
+    {
+      if (trap & 0x1)
+        {
+          if (core_cop)
+           sprintf (temp_string, "r%d", i);
+          else
+           sprintf (temp_string, "c%d", i);
+          strcat (string, temp_string);
+          if (trap & 0xfffe)
+           strcat (string, ",");
+        }
+      trap = trap >> 1;
+    }
+
+  strcat (string, "}");
+}
+
+/* START and END are relating 'allWords' struct, which is 48 bits size.
+
+                         START|--------|END
+           +---------+---------+---------+---------+
+           |         |    V    |     A   |   L     |
+           +---------+---------+---------+---------+
+                     0         16        32        48
+    words                [0]       [1]       [2]       */
+
+static parameter
+makelongparameter (ULONGLONG val, int start, int end)
+{
+  parameter p;
+
+  p.val = (dwordU) EXTRACT(val, 48 - end, end - start);
+  p.nbits = end - start;
+  return p;
+}
+
+/* Build a mask of the instruction's 'constant' opcode,
+   based on the instruction's printing flags.  */
+
+static unsigned long
+build_mask (void)
+{
+  unsigned int print_flags;
+  unsigned long mask;
+
+  print_flags = instruction->flags & FMT_CRX;
+  switch (print_flags)
+    {
+      case FMT_1:
+       mask = 0xF0F00000;
+       break;
+      case FMT_2:
+       mask = 0xFFF0FF00;
+       break;
+      case FMT_3:
+       mask = 0xFFF00F00;
+       break;
+      case FMT_4:
+       mask = 0xFFF0F000;
+       break;
+      case FMT_5:
+       mask = 0xFFF0FFF0;
+       break;
+      default:
+       mask = SBM(instruction->match_bits);
+       break;
+    }
+
+  return mask;
+}
+
+/* Search for a matching opcode. Return 1 for success, 0 for failure.  */
+
+static int
+match_opcode (void)
+{
+  unsigned long mask;
+
+  /* The instruction 'constant' opcode doewsn't exceed 32 bits.  */
+  unsigned long doubleWord = words[1] + (words[0] << 16);
+
+  /* Start searching from end of instruction table.  */
+  instruction = &crx_instruction[NUMOPCODES - 2];
+
+  /* Loop over instruction table until a full match is found.  */
+  while (instruction >= crx_instruction)
+    {
+      mask = build_mask ();
+      if ((doubleWord & mask) == BIN(instruction->match, instruction->match_bits))
+       return 1;
+      else
+       instruction--;
+    }
+  return 0;
+}
+
+/* Set the proper parameter value for different type of arguments.  */
+
+static void
+make_argument (argument * a, int start_bits)
+{
+  int inst_bit_size, total_size;
+  parameter p;
+
+  if ((instruction->size == 3) && a->size >= 16)
+    inst_bit_size = 48;
+  else
+    inst_bit_size = 32;
+
+  switch (a->type)
+    {
+    case arg_copr:
+    case arg_copsr:
+      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->cr = p.val;
+      break;
+
+    case arg_r:
+      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->r = p.val;
+      break;
+
+    case arg_ic:
+      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+
+      if ((p.nbits == 4) && cst4flag)
+        {
+         if (IS_INSN_TYPE (CMPBR_INS) && (p.val == ESCAPE_16_BIT))
+           {
+             /* A special case, where the value is actually stored
+                in the last 4 bits.  */
+             p = makelongparameter (allWords, 44, 48);
+             /* The size of the instruction should be incremented.  */
+             size_changed = 1;
+           }
+
+          if (p.val == 6)
+            p.val = -1;
+          else if (p.val == 13)
+            p.val = 48;
+          else if (p.val == 5)
+            p.val = -4;
+          else if (p.val == 10)
+            p.val = 32;
+          else if (p.val == 11)
+            p.val = 20;
+          else if (p.val == 9)
+            p.val = 16;
+        }
+
+      a->constant = p.val;
+      break;
+
+    case arg_icr:
+      a->scale = 0;
+      total_size = a->size + 10;  /* sizeof(rbase + ridx + scl2) = 10.  */
+      p = makelongparameter (allWords, inst_bit_size - total_size,
+                            inst_bit_size - (total_size - 4));
+      a->r = p.val;
+      p = makelongparameter (allWords, inst_bit_size - (total_size - 4),
+                            inst_bit_size - (total_size - 8));
+      a->i_r = p.val;
+      p = makelongparameter (allWords, inst_bit_size - (total_size - 8),
+                            inst_bit_size - (total_size - 10));
+      a->scale = p.val;
+      p = makelongparameter (allWords, inst_bit_size - (total_size - 10),
+                            inst_bit_size);
+      a->constant = p.val;
+      break;
+
+    case arg_rbase:
+      p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
+                            inst_bit_size - start_bits);
+      a->r = p.val;
+      break;
+
+    case arg_cr:
+      if (a->size <= 8)
+        {
+          p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
+                                inst_bit_size - start_bits);
+          a->r = p.val;
+          /* Case for opc4 r dispu rbase.  */
+          p = makelongparameter (allWords, inst_bit_size - (start_bits + 8),
+                                inst_bit_size - (start_bits + 4));
+        }
+      else
+        {
+         /* The 'rbase' start_bits is always relative to a 32-bit data type.  */
+          p = makelongparameter (allWords, 32 - (start_bits + 4),
+                                32 - start_bits);
+          a->r = p.val;
+          p = makelongparameter (allWords, 32 - start_bits,
+                                inst_bit_size);
+        }
+      if ((p.nbits == 4) && cst4flag)
+        {
+          if (instruction->flags & DISPUW4)
+           p.val *= 2;
+          else if (instruction->flags & DISPUD4)
+           p.val *= 4;
+        }
+      a->constant = p.val;
+      break;
+
+    case arg_c:
+      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
+                            inst_bit_size - start_bits);
+      a->constant = p.val;
+      break;
+    default:
+      break;
+    }
+}
+
+/*  Print a single argument.  */
+
+static void
+print_arg (argument *a, struct disassemble_info *info)
+{
+  LONGLONG longdisp, mask;
+  char sign_flag;
+  int op_index = 0;
+  char string[200];
+  PTR stream = info->stream;
+  fprintf_ftype func = info->fprintf_func;
+
+  switch (a->type)
+    {
+    case arg_copr:
+      func (stream, "%s", getcopregname (a->cr, CRX_C_REGTYPE));
+      break;
+
+    case arg_copsr:
+      func (stream, "%s", getcopregname (a->cr, CRX_CS_REGTYPE));
+      break;
+
+    case arg_r:
+      if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
+       func (stream, "%s", getprocregname (a->r));
+      else
+       func (stream, "%s", getregname (a->r));
+      break;
+
+    case arg_ic:
+      if (IS_INSN_MNEMONIC ("excp"))
+       func (stream, "%s", gettrapstring (a->constant));
+
+      else if (IS_INSN_MNEMONIC ("cinv"))
+       func (stream, "%s", getcinvstring (a->constant));
+
+      else if (INST_HAS_REG_LIST)
+        {
+          if (!IS_INSN_TYPE (COP_REG_INS))
+            {
+              getregliststring (a->constant, string, 1);
+              func (stream, "%s", string);
+            }
+          else
+            {
+              /*  Check for proper argument number.  */
+              if (processing_argument_number == 2)
+                {
+                  getregliststring (a->constant, string, 0);
+                  func (stream, "%s", string);
+                }
+              else
+               func (stream, "$0x%x", a->constant);
+            }
+        }
+      else
+       func (stream, "$0x%x", a->constant);
+      break;
+
+    case arg_icr:
+      func (stream, "0x%x(%s,%s,%d)", a->constant, getregname (a->r),
+           getregname (a->i_r), powerof2 (a->scale));
+      break;
+
+    case arg_rbase:
+      func (stream, "(%s)", getregname (a->r));
+      break;
+
+    case arg_cr:
+      func (stream, "0x%x(%s)", a->constant, getregname (a->r));
+
+      if (IS_INSN_TYPE (LD_STOR_INS_INC))
+       func (stream, "+");
+      break;
+
+    case arg_c:
+      /* Removed the *2 part as because implicit zeros are no more required.
+        Have to fix this as this needs a bit of extension in terms of branchins.
+        Have to add support for cmp and branch instructions.  */
+      if (IS_INSN_TYPE (BRANCH_INS) || IS_INSN_MNEMONIC ("bal")
+         || IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (DCR_BRANCH_INS)
+         || IS_INSN_TYPE (COP_BRANCH_INS))
+        {
+          func (stream, "%c", '*');
+          longdisp = a->constant;
+          longdisp <<= 1;
+          sign_flag = '+';
+
+          switch (a->size)
+            {
+            case 8:
+           case 16:
+           case 24:
+           case 32:
+             mask = ((LONGLONG)1 << a->size) - 1;
+              if (longdisp & ((LONGLONG)1 << a->size))
+                {
+                  sign_flag = '-';
+                  longdisp = ~(longdisp) + 1;
+                }
+              a->constant = (unsigned long int) (longdisp & mask);
+              break;
+            default:
+             func (stream,
+                   "Wrong offset used in branch/bal instruction");
+              break;
+            }
+
+         func (stream, "%c", sign_flag);
+        }
+      /* For branch Neq instruction it is 2*offset + 2.  */
+      if (IS_INSN_TYPE (BRANCH_NEQ_INS))
+       a->constant = 2 * a->constant + 2;
+      if (IS_INSN_TYPE (LD_STOR_INS_INC)
+         || IS_INSN_TYPE (LD_STOR_INS)
+         || IS_INSN_TYPE (STOR_IMM_INS)
+         || IS_INSN_TYPE (CSTBIT_INS))
+        {
+          op_index = instruction->flags & REVERSE_MATCH ? 0 : 1;
+          if (instruction->operands[op_index].op_type == abs16)
+           a->constant |= 0xFFFF0000;
+        }
+      func (stream, "0x%x", a->constant);
+      break;
+    default:
+      break;
+    }
+}
+
+/* Print all the arguments of CURRINSN instruction.  */
+
+static void
+print_arguments (ins *currInsn, struct disassemble_info *info)
+{
+  int i;
+
+  for (i = 0; i < currInsn->nargs; i++)
+    {
+      processing_argument_number = i;
+
+      print_arg (&currInsn->arg[i], info);
+
+      if (i != currInsn->nargs - 1)
+       info->fprintf_func (info->stream, ", ");
+    }
+}
+
+/* Build the instruction's arguments.  */
+
+static void
+make_instruction (void)
+{
+  int i;
+  unsigned int temp_value, shift;
+  argument a;
+
+  for (i = 0; i < currInsn.nargs; i++)
+    {
+      a.type = getargtype (instruction->operands[i].op_type);
+      if (instruction->operands[i].op_type == cst4
+         || instruction->operands[i].op_type == rbase_cst4)
+       cst4flag = 1;
+      a.size = getbits (instruction->operands[i].op_type);
+      shift = instruction->operands[i].shift;
+
+      make_argument (&a, shift);
+      currInsn.arg[i] = a;
+    }
+
+  /* Calculate instruction size (in bytes).  */
+  currInsn.size = instruction->size + (size_changed ? 1 : 0);
+  currInsn.size *= 2;
+
+  /* Swapping first and second arguments.  */
+  if (IS_INSN_TYPE (COP_BRANCH_INS))
+    {
+      temp_value = currInsn.arg[0].constant;
+      currInsn.arg[0].constant = currInsn.arg[1].constant;
+      currInsn.arg[1].constant = temp_value;
+    }
+}
+
+/* Retrieve a single word from a given memory address.  */
+
+static wordU
+get_word_at_PC (bfd_vma memaddr, struct disassemble_info *info)
+{
+  bfd_byte buffer[4];
+  int status;
+  wordU insn = 0;
+
+  status = info->read_memory_func (memaddr, buffer, 2, info);
+
+  if (status == 0)
+    insn = (wordU) bfd_getl16 (buffer);
+
+  return insn;
+}
+
+/* Retrieve multiple words (3) from a given memory address.  */
+
+static void
+get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
+{
+  int i;
+  bfd_vma mem;
+
+  for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
+    words[i] = get_word_at_PC (mem, info);
+
+  allWords =
+    ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
+}
+
+/* Prints the instruction by calling print_arguments after proper matching.  */
+
+int
+print_insn_crx (memaddr, info)
+     bfd_vma memaddr;
+     struct disassemble_info *info;
+{
+  int is_decoded;     /* Nonzero means instruction has a match.  */
+
+  /* Initialize global variables.  */
+  cst4flag = 0;
+  size_changed = 0;
+
+  /* Retrieve the encoding from current memory location.  */
+  get_words_at_PC (memaddr, info);
+  /* Find a matching opcode in table.  */
+  is_decoded = match_opcode ();
+  /* If found, print the instruction's mnemonic and arguments.  */
+  if (is_decoded > 0 && (words[0] << 16 || words[1]) != 0)
+    {
+      info->fprintf_func (info->stream, "%s", instruction->mnemonic);
+      if ((currInsn.nargs = get_number_of_operands ()) != 0)
+       info->fprintf_func (info->stream, "\t");
+      make_instruction ();
+      print_arguments (&currInsn, info);
+      return currInsn.size;
+    }
+
+  /* No match found.  */
+  info->fprintf_func (info->stream,"%s ",ILLEGAL);
+  return 2;
+}
diff --git a/opcodes/crx-opc.c b/opcodes/crx-opc.c
new file mode 100644 (file)
index 0000000..b01addf
--- /dev/null
@@ -0,0 +1,675 @@
+/* crx-opc.c -- Table of opcodes for the CRX processor.
+   Copyright 2004 Free Software Foundation, Inc.
+   Contributed by Tomer Levi NSC, Israel.
+   Originally written for GAS 2.12 by Tomer Levi.
+
+   This file is part of GAS, GDB and the GNU binutils.
+
+   GAS, GDB, and GNU binutils 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, or (at your
+   option) any later version.
+
+   GAS, GDB, and GNU binutils are distributed in the hope that they 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.  */
+
+#include <stdio.h>
+#include "libiberty.h"
+#include "symcat.h"
+#include "opcode/crx.h"
+
+const inst crx_instruction[] =
+{
+/* Create an arithmetic instruction - INST[bw].  */
+#define  ARITH_BYTE_INST(NAME, OPC) \
+  /* opc8 cst4 r */                                                       \
+  {NAME, 1, OPC,  24, ARITH_BYTE_INS, {{cst4,20}, {regr,16}}},            \
+  /* opc8 i16 r */                                                        \
+  {NAME, 2, (OPC<<4)+0xE, 20, ARITH_BYTE_INS, {{i16,0},        {regr,16}}},       \
+  /* opc8 r r */                                                          \
+  {NAME, 1, OPC+0x40, 24, ARITH_BYTE_INS, {{regr,20}, {regr,16}}}
+
+  ARITH_BYTE_INST ("addub", 0x0),
+  ARITH_BYTE_INST ("addb",  0x1),
+  ARITH_BYTE_INST ("addcb", 0x2),
+  ARITH_BYTE_INST ("andb",  0x3),
+  ARITH_BYTE_INST ("cmpb",  0x4),
+  ARITH_BYTE_INST ("movb",  0x5),
+  ARITH_BYTE_INST ("orb",   0x6),
+  ARITH_BYTE_INST ("subb",  0x7),
+  ARITH_BYTE_INST ("subcb", 0x8),
+  ARITH_BYTE_INST ("xorb",  0x9),
+  ARITH_BYTE_INST ("mulb",  0xA),
+
+  ARITH_BYTE_INST ("adduw", 0x10),
+  ARITH_BYTE_INST ("addw",  0x11),
+  ARITH_BYTE_INST ("addcw", 0x12),
+  ARITH_BYTE_INST ("andw",  0x13),
+  ARITH_BYTE_INST ("cmpw",  0x14),
+  ARITH_BYTE_INST ("movw",  0x15),
+  ARITH_BYTE_INST ("orw",   0x16),
+  ARITH_BYTE_INST ("subw",  0x17),
+  ARITH_BYTE_INST ("subcw", 0x18),
+  ARITH_BYTE_INST ("xorw",  0x19),
+  ARITH_BYTE_INST ("mulw",  0x1A),
+
+/* Create an arithmetic instruction - INST[d].  */
+#define  ARITH_INST(NAME, OPC) \
+  /* opc8 cst4 r */                                                  \
+  {NAME, 1, OPC,  24, ARITH_INS, {{cst4,20}, {regr,16}}},            \
+  /* opc8 i16 r */                                                   \
+  {NAME, 2, (OPC<<4)+0xE, 20, ARITH_INS, {{i16,0},   {regr,16}}},     \
+  /* opc8 i32 r */                                                   \
+  {NAME, 3, (OPC<<4)+0xF, 20, ARITH_INS, {{i32,0},   {regr,16}}},     \
+  /* opc8 r r */                                                     \
+  {NAME, 1, OPC+0x40, 24, ARITH_INS, {{regr,20}, {regr,16}}}
+
+  ARITH_INST ("addud", 0x20),
+  ARITH_INST ("addd",  0x21),
+  ARITH_INST ("addcd", 0x22),
+  ARITH_INST ("andd",  0x23),
+  ARITH_INST ("cmpd",  0x24),
+  ARITH_INST ("movd",  0x25),
+  ARITH_INST ("ord",   0x26),
+  ARITH_INST ("subd",  0x27),
+  ARITH_INST ("subcd", 0x28),
+  ARITH_INST ("xord",  0x29),
+  ARITH_INST ("muld",  0x2A),
+
+/* Create a shift instruction.  */
+#define  SHIFT_INST(NAME, OPRD, OPC1, SHIFT1, OPC2) \
+  /* OPRD=i3 -->> opc9 i3 r */                                       \
+  /* OPRD=i4 -->> opc8 i4 r */                                       \
+  /* OPRD=i5 -->> opc7 i5 r */                                       \
+  {NAME, 1, OPC1, SHIFT1, SHIFT_INS, {{OPRD,20}, {regr,16}}},        \
+  /* opc8 r r */                                                     \
+  {NAME, 1, OPC2, 24, SHIFT_INS, {{regr,20}, {regr,16}}}
+
+  SHIFT_INST ("sllb", i3, 0x1F8, 23, 0x4D),
+  SHIFT_INST ("srlb", i3, 0x1F9, 23, 0x4E),
+  SHIFT_INST ("srab", i3, 0x1FA, 23, 0x4F),
+
+  SHIFT_INST ("sllw", i4, 0xB6,  24, 0x5D),
+  SHIFT_INST ("srlw", i4, 0xB7,  24, 0x5E),
+  SHIFT_INST ("sraw", i4, 0xB8,  24, 0x5F),
+
+  SHIFT_INST ("slld", i5, 0x78,  25, 0x6D),
+  SHIFT_INST ("srld", i5, 0x79,  25, 0x6E),
+  SHIFT_INST ("srad", i5, 0x7A,  25, 0x6F),
+
+/* Create a conditional branch instruction.  */
+#define  BRANCH_INST(NAME, OPC) \
+  /* opc4 c4 dispe9 */                                             \
+  {NAME,  1, OPC, 24, BRANCH_INS | RELAXABLE, {{d9,16}}},          \
+  /* opc4 c4 disps17 */                                                    \
+  {NAME,  2, (OPC<<8)+0x7E, 16,        BRANCH_INS | RELAXABLE, {{d17,0}}}, \
+  /* opc4 c4 disps33 */                                                    \
+  {NAME,  3, (OPC<<8)+0x7F, 16,        BRANCH_INS | RELAXABLE, {{d33,0}}}
+
+  BRANCH_INST ("beq", 0x70),
+  BRANCH_INST ("bne", 0x71),
+  BRANCH_INST ("bcs", 0x72),
+  BRANCH_INST ("bcc", 0x73),
+  BRANCH_INST ("bhi", 0x74),
+  BRANCH_INST ("bls", 0x75),
+  BRANCH_INST ("bgt", 0x76),
+  BRANCH_INST ("ble", 0x77),
+  BRANCH_INST ("bfs", 0x78),
+  BRANCH_INST ("bfc", 0x79),
+  BRANCH_INST ("blo", 0x7A),
+  BRANCH_INST ("bhs", 0x7B),
+  BRANCH_INST ("blt", 0x7C),
+  BRANCH_INST ("bge", 0x7D),
+  BRANCH_INST ("br",  0x7E),
+
+/* Create a 'Branch if Equal to 0' instruction.  */
+#define  BRANCH_NEQ_INST(NAME, OPC) \
+  /* opc8 dispu5 r */                                          \
+  {NAME,  1, OPC, 24, BRANCH_NEQ_INS, {{regr,16}, {d5,20}}}
+
+  BRANCH_NEQ_INST ("beq0b",  0xB0),
+  BRANCH_NEQ_INST ("bne0b",  0xB1),
+  BRANCH_NEQ_INST ("beq0w",  0xB2),
+  BRANCH_NEQ_INST ("bne0w",  0xB3),
+  BRANCH_NEQ_INST ("beq0d",  0xB4),
+  BRANCH_NEQ_INST ("bne0d",  0xB5),
+
+/* Create instruction with no operands.  */
+#define  NO_OP_INST(NAME, OPC) \
+  /* opc16 */                          \
+  {NAME,  1, OPC, 16, 0, {{0, 0}}}
+
+  NO_OP_INST ("nop",   0x3002),
+  NO_OP_INST ("retx",  0x3003),
+  NO_OP_INST ("di",    0x3004),
+  NO_OP_INST ("ei",    0x3005),
+  NO_OP_INST ("wait",  0x3006),
+  NO_OP_INST ("eiwait",        0x3007),
+
+/* Create a 'Compare & Branch' instruction.  */
+#define  CMPBR_INST(NAME, OPC1, OPC2, C4) \
+  /* opc12 r r c4 disps9 */                                                                            \
+  {NAME, 2, ((0x300+OPC1)<<12)+C4,  8, CMPBR_INS | FMT_3 | RELAXABLE, {{regr,16}, {regr,12}, {d9,0}}},  \
+  /* opc12 r r c4 disps25 */                                                                           \
+  {NAME, 3, ((0x310+OPC1)<<12)+C4,  8, CMPBR_INS | FMT_3 | RELAXABLE, {{regr,16}, {regr,12}, {d25,0}}}, \
+  /* opc12 i4cst4 r c4 disps9 */                                                                       \
+  {NAME, 2, ((0x300+OPC2)<<12)+C4,  8, CMPBR_INS | FMT_3 | RELAXABLE, {{cst4,16}, {regr,12}, {d9,0}}},  \
+  /* opc12 i4cst4 r c4 disps25 */                                                                      \
+  {NAME, 3, ((0x310+OPC2)<<12)+C4,  8, CMPBR_INS | FMT_3 | RELAXABLE, {{cst4,16}, {regr,12}, {d25,0}}}
+
+  CMPBR_INST ("cmpbeqb", 0x8, 0xC, 0x0),
+  CMPBR_INST ("cmpbneb", 0x8, 0xC, 0x1),
+  CMPBR_INST ("cmpbhib", 0x8, 0xC, 0x4),
+  CMPBR_INST ("cmpblsb", 0x8, 0xC, 0x5),
+  CMPBR_INST ("cmpbgtb", 0x8, 0xC, 0x6),
+  CMPBR_INST ("cmpbleb", 0x8, 0xC, 0x7),
+  CMPBR_INST ("cmpblob", 0x8, 0xC, 0xA),
+  CMPBR_INST ("cmpbhsb", 0x8, 0xC, 0xB),
+  CMPBR_INST ("cmpbltb", 0x8, 0xC, 0xC),
+  CMPBR_INST ("cmpbgeb", 0x8, 0xC, 0xD),
+
+  CMPBR_INST ("cmpbeqw", 0x9, 0xD, 0x0),
+  CMPBR_INST ("cmpbnew", 0x9, 0xD, 0x1),
+  CMPBR_INST ("cmpbhiw", 0x9, 0xD, 0x4),
+  CMPBR_INST ("cmpblsw", 0x9, 0xD, 0x5),
+  CMPBR_INST ("cmpbgtw", 0x9, 0xD, 0x6),
+  CMPBR_INST ("cmpblew", 0x9, 0xD, 0x7),
+  CMPBR_INST ("cmpblow", 0x9, 0xD, 0xA),
+  CMPBR_INST ("cmpbhsw", 0x9, 0xD, 0xB),
+  CMPBR_INST ("cmpbltw", 0x9, 0xD, 0xC),
+  CMPBR_INST ("cmpbgew", 0x9, 0xD, 0xD),
+
+  CMPBR_INST ("cmpbeqd", 0xA, 0xE, 0x0),
+  CMPBR_INST ("cmpbned", 0xA, 0xE, 0x1),
+  CMPBR_INST ("cmpbhid", 0xA, 0xE, 0x4),
+  CMPBR_INST ("cmpblsd", 0xA, 0xE, 0x5),
+  CMPBR_INST ("cmpbgtd", 0xA, 0xE, 0x6),
+  CMPBR_INST ("cmpbled", 0xA, 0xE, 0x7),
+  CMPBR_INST ("cmpblod", 0xA, 0xE, 0xA),
+  CMPBR_INST ("cmpbhsd", 0xA, 0xE, 0xB),
+  CMPBR_INST ("cmpbltd", 0xA, 0xE, 0xC),
+  CMPBR_INST ("cmpbged", 0xA, 0xE, 0xD),
+
+/* Create an instruction using a single register operand.  */
+#define  REG1_INST(NAME, OPC) \
+  /* opc8 c4 r */                        \
+  {NAME,  1, OPC, 20, 0, {{regr,16}}}
+
+  /* JCond instructions        */
+  REG1_INST ("jeq",  0xBA0),
+  REG1_INST ("jne",  0xBA1),
+  REG1_INST ("jcs",  0xBA2),
+  REG1_INST ("jcc",  0xBA3),
+  REG1_INST ("jhi",  0xBA4),
+  REG1_INST ("jls",  0xBA5),
+  REG1_INST ("jgt",  0xBA6),
+  REG1_INST ("jle",  0xBA7),
+  REG1_INST ("jfs",  0xBA8),
+  REG1_INST ("jfc",  0xBA9),
+  REG1_INST ("jlo",  0xBAA),
+  REG1_INST ("jhs",  0xBAB),
+  REG1_INST ("jlt",  0xBAC),
+  REG1_INST ("jge",  0xBAD),
+  REG1_INST ("jump", 0xBAE),
+
+  /* SCond instructions */
+  REG1_INST ("seq",  0xBB0),
+  REG1_INST ("sne",  0xBB1),
+  REG1_INST ("scs",  0xBB2),
+  REG1_INST ("scc",  0xBB3),
+  REG1_INST ("shi",  0xBB4),
+  REG1_INST ("sls",  0xBB5),
+  REG1_INST ("sgt",  0xBB6),
+  REG1_INST ("sle",  0xBB7),
+  REG1_INST ("sfs",  0xBB8),
+  REG1_INST ("sfc",  0xBB9),
+  REG1_INST ("slo",  0xBBA),
+  REG1_INST ("shs",  0xBBB),
+  REG1_INST ("slt",  0xBBC),
+  REG1_INST ("sge",  0xBBD),
+
+/* Create an instruction using two register operands.  */
+#define  REG2_INST(NAME, OPC) \
+  /* opc24 r r  OR  opc20 c4 r r */                          \
+  {NAME,  2, 0x300800+OPC,  8, 0, {{regr,4}, {regr,0}}}
+
+  /* MULTIPLY INSTRUCTIONS */
+  REG2_INST ("macsb",  0x40),
+  REG2_INST ("macub",  0x41),
+  REG2_INST ("macqb",  0x42),
+
+  REG2_INST ("macsw",  0x50),
+  REG2_INST ("macuw",  0x51),
+  REG2_INST ("macqw",  0x52),
+
+  REG2_INST ("macsd",  0x60),
+  REG2_INST ("macud",  0x61),
+  REG2_INST ("macqd",  0x62),
+
+  REG2_INST ("mullsd", 0x65),
+  REG2_INST ("mullud", 0x66),
+
+  REG2_INST ("mulsbw", 0x3B),
+  REG2_INST ("mulubw", 0x3C),
+  REG2_INST ("mulswd", 0x3D),
+  REG2_INST ("muluwd", 0x3E),
+
+  /*  SIGNEXTEND STUFF    */
+  REG2_INST ("sextbw", 0x30),
+  REG2_INST ("sextbd", 0x31),
+  REG2_INST ("sextwd", 0x32),
+  REG2_INST ("zextbw", 0x34),
+  REG2_INST ("zextbd", 0x35),
+  REG2_INST ("zextwd", 0x36),
+
+  REG2_INST ("bswap",  0x3F),
+
+  REG2_INST ("maxsb",  0x80),
+  REG2_INST ("minsb",  0x81),
+  REG2_INST ("maxub",  0x82),
+  REG2_INST ("minub",  0x83),
+  REG2_INST ("absb",   0x84),
+  REG2_INST ("negb",   0x85),
+  REG2_INST ("cntl0b", 0x86),
+  REG2_INST ("cntl1b", 0x87),
+  REG2_INST ("popcntb",0x88),
+  REG2_INST ("rotlb",  0x89),
+  REG2_INST ("rotrb",  0x8A),
+  REG2_INST ("mulqb",  0x8B),
+  REG2_INST ("addqb",  0x8C),
+  REG2_INST ("subqb",  0x8D),
+  REG2_INST ("cntlsb", 0x8E),
+
+  REG2_INST ("maxsw",  0x90),
+  REG2_INST ("minsw",  0x91),
+  REG2_INST ("maxuw",  0x92),
+  REG2_INST ("minuw",  0x93),
+  REG2_INST ("absw",   0x94),
+  REG2_INST ("negw",   0x95),
+  REG2_INST ("cntl0w", 0x96),
+  REG2_INST ("cntl1w", 0x97),
+  REG2_INST ("popcntw",0x98),
+  REG2_INST ("rotlw",  0x99),
+  REG2_INST ("rotrw",  0x9A),
+  REG2_INST ("mulqw",  0x9B),
+  REG2_INST ("addqw",  0x9C),
+  REG2_INST ("subqw",  0x9D),
+  REG2_INST ("cntlsw", 0x9E),
+
+  REG2_INST ("maxsd",  0xA0),
+  REG2_INST ("minsd",  0xA1),
+  REG2_INST ("maxud",  0xA2),
+  REG2_INST ("minud",  0xA3),
+  REG2_INST ("absd",   0xA4),
+  REG2_INST ("negd",   0xA5),
+  REG2_INST ("cntl0d", 0xA6),
+  REG2_INST ("cntl1d", 0xA7),
+  REG2_INST ("popcntd",0xA8),
+  REG2_INST ("rotld",  0xA9),
+  REG2_INST ("rotrd",  0xAA),
+  REG2_INST ("mulqd",  0xAB),
+  REG2_INST ("addqd",  0xAC),
+  REG2_INST ("subqd",  0xAD),
+  REG2_INST ("cntlsd", 0xAE),
+
+/* Conditional move instructions */
+  REG2_INST ("cmoveqd", 0x70),
+  REG2_INST ("cmovned", 0x71),
+  REG2_INST ("cmovcsd", 0x72),
+  REG2_INST ("cmovccd", 0x73),
+  REG2_INST ("cmovhid", 0x74),
+  REG2_INST ("cmovlsd", 0x75),
+  REG2_INST ("cmovgtd", 0x76),
+  REG2_INST ("cmovled", 0x77),
+  REG2_INST ("cmovfsd", 0x78),
+  REG2_INST ("cmovfcd", 0x79),
+  REG2_INST ("cmovlod", 0x7A),
+  REG2_INST ("cmovhsd", 0x7B),
+  REG2_INST ("cmovltd", 0x7C),
+  REG2_INST ("cmovged", 0x7D),
+
+/* Load instructions (from memory to register).  */
+#define  LD_REG_INST(NAME, OPC1, OPC2, DISP) \
+  /* opc12 r abs16 */                                                                   \
+  {NAME,  2, 0x320+OPC1,  20, LD_STOR_INS | REVERSE_MATCH, {{abs16,0}, {regr,16}}},     \
+  /* opc12 r abs32 */                                                                   \
+  {NAME,  3, 0x330+OPC1,  20, LD_STOR_INS | REVERSE_MATCH, {{abs32,0}, {regr,16}}},     \
+  /* opc4 r c4 rbase */                                                                         \
+  {NAME,  1, ((0x8+OPC2)<<8),  20, LD_STOR_INS | DISP | FMT_1 | REVERSE_MATCH, {{rbase,20}, {regr,24}}},\
+  /* opc4 r rbase dispu[bwd]4 */                                                        \
+  {NAME,  1, 0x8+OPC2,  28, LD_STOR_INS | DISP | REVERSE_MATCH, {{rbase_cst4,16}, {regr,24}}},          \
+  /* opc4 r rbase disps16 */                                                            \
+  {NAME,  2, ((0x8+OPC2)<<8)+0xE,  20, LD_STOR_INS | DISP | FMT_1 | REVERSE_MATCH, {{rbase_dispu16,16}, {regr,24}}}, \
+  /* opc4 r rbase disps32 */                                                            \
+  {NAME,  3, ((0x8+OPC2)<<8)+0xF,  20, LD_STOR_INS | FMT_1 | REVERSE_MATCH, {{rbase_dispu32,16}, {regr,24}}}, \
+  /* opc12 r rbase */                                                                   \
+  {NAME,  2, 0x328+OPC1,  20, LD_STOR_INS_INC | REVERSE_MATCH, {{rbase,12}, {regr,16}}},                \
+  /* opc12 r rbase disps12 */                                                           \
+  {NAME,  2, 0x328+OPC1,  20, LD_STOR_INS_INC | REVERSE_MATCH, {{rbase_dispu12,12}, {regr,16}}},        \
+  /* opc12 r rbase ridx scl2 disps6 */                                                  \
+  {NAME,  2, 0x32C+OPC1,  20, LD_STOR_INS | REVERSE_MATCH, {{rbase_ridx_scl2_dispu6,0}, {regr,16}}},    \
+  /* opc12 r rbase ridx scl2 disps22 */                                                         \
+  {NAME,  3, 0x33C+OPC1,  20, LD_STOR_INS | REVERSE_MATCH, {{rbase_ridx_scl2_dispu22,0}, {regr,16}}}
+
+  LD_REG_INST ("loadb", 0x0, 0x0, DISPUB4),
+  LD_REG_INST ("loadw", 0x1, 0x1, DISPUW4),
+  LD_REG_INST ("loadd", 0x2, 0x2, DISPUD4),
+
+/* Store instructions (from Register to Memory).  */
+#define  ST_REG_INST(NAME, OPC1, OPC2, DISP) \
+  /* opc12 r abs16 */                                                                   \
+  {NAME,  2, 0x320+OPC1,  20, LD_STOR_INS, {{regr,16}, {abs16,0}}},                     \
+  /* opc12 r abs32 */                                                                   \
+  {NAME,  3, 0x330+OPC1,  20, LD_STOR_INS, {{regr,16}, {abs32,0}}},                     \
+  /* opc4 r c4 rbase */                                                                         \
+  {NAME,  1, ((0x8+OPC2)<<8),  20, LD_STOR_INS | DISP | FMT_1, {{regr,24}, {rbase,20}}},\
+  /* opc4 r rbase dispu[bwd]4 */                                                        \
+  {NAME,  1, 0x8+OPC2,  28, LD_STOR_INS | DISP, {{regr,24}, {rbase_cst4,16}}},          \
+  /* opc4 r rbase disps16 */                                                            \
+  {NAME,  2, ((0x8+OPC2)<<8)+0xE,  20, LD_STOR_INS | DISP | FMT_1, {{regr,24}, {rbase_dispu16,16}}}, \
+  /* opc4 r rbase disps32 */                                                            \
+  {NAME,  3, ((0x8+OPC2)<<8)+0xF,  20, LD_STOR_INS | FMT_1, {{regr,24}, {rbase_dispu32,16}}}, \
+  /* opc12 r rbase */                                                                   \
+  {NAME,  2, 0x328+OPC1,  20, LD_STOR_INS_INC, {{regr,16}, {rbase,12}}},                \
+  /* opc12 r rbase disps12 */                                                           \
+  {NAME,  2, 0x328+OPC1,  20, LD_STOR_INS_INC, {{regr,16}, {rbase_dispu12,12}}},        \
+  /* opc12 r rbase ridx scl2 disps6 */                                                  \
+  {NAME,  2, 0x32C+OPC1,  20, LD_STOR_INS, {{regr,16}, {rbase_ridx_scl2_dispu6,0}}},    \
+  /* opc12 r rbase ridx scl2 disps22 */                                                         \
+  {NAME,  3, 0x33C+OPC1,  20, LD_STOR_INS, {{regr,16}, {rbase_ridx_scl2_dispu22,0}}}
+
+/* Store instructions (Immediate to Memory).  */
+#define  ST_I_INST(NAME, OPC) \
+  /* opc12 i4 abs16 */                                                          \
+  {NAME,  2, 0x360+OPC,        20, STOR_IMM_INS, {{i4,16}, {abs16,0}}},                 \
+  /* opc12 i4 abs32 */                                                          \
+  {NAME,  3, 0x370+OPC,        20, STOR_IMM_INS, {{i4,16}, {abs32,0}}},                 \
+  /* opc12 i4 c4 rbase */                                                       \
+  {NAME,  1, 0x368+OPC,        20, LD_STOR_INS_INC, {{i4,16}, {rbase,12}}},             \
+  /* opc12 i4 rbase disps12 */                                                  \
+  {NAME,  2, 0x368+OPC,        20, LD_STOR_INS_INC, {{i4,16}, {rbase_dispu12,12}}},     \
+  /* opc4 i4 c4 rbase */                                                        \
+  {NAME,  1, 0x364+OPC,        20, STOR_IMM_INS, {{i4,16}, {rbase,12}}},                \
+  /* opc12 i4 rbase disps12 */                                                  \
+  {NAME,  2, 0x364+OPC,        20, STOR_IMM_INS, {{i4,16}, {rbase_dispu12,12}}},        \
+  /* opc12 i4 rbase disps28 */                                                  \
+  {NAME,  3, 0x374+OPC,        20, STOR_IMM_INS, {{i4,16}, {rbase_dispu28,12}}},        \
+  /* opc12 i4 rbase ridx scl2 disps6 */                                                 \
+  {NAME,  2, 0x36C+OPC,        20, STOR_IMM_INS, {{i4,16}, {rbase_ridx_scl2_dispu6,0}}},\
+  /* opc12 i4 rbase ridx scl2 disps22 */                                        \
+  {NAME,  3, 0x37C+OPC,        20, STOR_IMM_INS, {{i4,16}, {rbase_ridx_scl2_dispu22,0}}}
+
+  ST_REG_INST ("storb", 0x20, 0x4, DISPUB4),
+  ST_I_INST ("storb",  0x0),
+
+  ST_REG_INST ("storw", 0x21, 0x5, DISPUW4),
+  ST_I_INST ("storw",  0x1),
+
+  ST_REG_INST ("stord", 0x22, 0x6, DISPUD4),
+  ST_I_INST ("stord",  0x2),
+
+/* Create a bit instruction.  */
+#define  CSTBIT_INST(NAME, OP, OPC1, DIFF, SHIFT, OPC2) \
+  /* OP=i3 -->> opc13 i3 */                                                              \
+  /* OP=i4 -->> opc12 i4 */                                                              \
+  /* OP=i5 -->> opc11 i5 */                                                              \
+                                                                                         \
+  /* opcNN iN abs16 */                                                                   \
+  {NAME,  2, OPC1+0*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {abs16,0}}},                      \
+  /* opcNN iN abs32 */                                                                   \
+  {NAME,  3, OPC1+1*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {abs32,0}}},                      \
+  /* opcNN iN rbase */                                                                   \
+  {NAME,  1, OPC2,  SHIFT+4,  CSTBIT_INS, {{OP,20}, {rbase,16}}},                        \
+  /* opcNN iN rbase disps12 */                                                           \
+  {NAME,  2, OPC1+2*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_dispu12,12}}},             \
+  /* opcNN iN rbase disps28 */                                                           \
+  {NAME,  3, OPC1+3*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_dispu28,12}}},             \
+  /* opcNN iN rbase ridx scl2 disps6 */                                                          \
+  {NAME,  2, OPC1+4*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_ridx_scl2_dispu6,0}}},     \
+  /* opcNN iN rbase ridx scl2 disps22 */                                                 \
+  {NAME,  3, OPC1+5*DIFF, SHIFT, CSTBIT_INS, {{OP,16}, {rbase_ridx_scl2_dispu22,0}}}
+
+  CSTBIT_INST ("cbitb", i3, 0x700, 0x20, 19, 0x1FC),
+  CSTBIT_INST ("cbitw", i4, 0x382, 0x10, 20, 0xBD),
+  CSTBIT_INST ("cbitd", i5, 0x1C3, 0x8,  21, 0x7B),
+  {"cbitd",   2, 0x300838,  8, CSTBIT_INS, {{regr,4}, {regr,0}}},
+  {"cbitd",   2, 0x18047B,  9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+
+  CSTBIT_INST ("sbitb", i3, 0x701, 0x20, 19, 0x1FD),
+  CSTBIT_INST ("sbitw", i4, 0x383, 0x10, 20, 0xBE),
+  CSTBIT_INST ("sbitd", i5, 0x1C4, 0x8,  21, 0x7C),
+  {"sbitd",   2, 0x300839,  8, CSTBIT_INS, {{regr,4}, {regr,0}}},
+  {"sbitd",   2, 0x18047C,  9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+
+  CSTBIT_INST ("tbitb", i3, 0x702, 0x20, 19, 0x1FE),
+  CSTBIT_INST ("tbitw", i4, 0x384, 0x10, 20, 0xBF),
+  CSTBIT_INST ("tbitd", i5, 0x1C5, 0x8,  21, 0x7D),
+  {"tbitd",   2, 0x30083A,  8, CSTBIT_INS, {{regr,4}, {regr,0}}},
+  {"tbitd",   2, 0x18047D,  9, CSTBIT_INS, {{i5,4}, {regr,0}}},
+
+/* Instructions including a register list (opcode is represented as a mask).  */
+#define  REGLIST_INST(NAME, OPC) \
+  /* opc12 r mask16 */                                   \
+  {NAME,  2, OPC, 20, REG_LIST, {{regr,16}, {i16,0}}}
+
+  REG1_INST ("getrfid",        0xFF9),
+  REG1_INST ("setrfid",        0xFFA),
+
+  REGLIST_INST ("push",         0x346),
+  REG1_INST ("push",    0xFFB),
+  REGLIST_INST ("pushx", 0x347),
+
+  REGLIST_INST ("pop",  0x324),
+  REG1_INST ("pop",     0xFFC),
+  REGLIST_INST ("popx",         0x327),
+
+  REGLIST_INST ("popret", 0x326),
+  REG1_INST ("popret",    0xFFD),
+
+  REGLIST_INST ("loadm",  0x324),
+  REGLIST_INST ("loadma", 0x325),
+  REGLIST_INST ("popa",          0x325),
+
+  REGLIST_INST ("storm",  0x344),
+  REGLIST_INST ("storma", 0x345),
+
+/* Create a branch instruction.  */
+#define  BR_INST(NAME, OPC1, OPC2, INS_TYPE) \
+  /* opc12 r disps17 */                                                      \
+  {NAME,  2, OPC1,  20, INS_TYPE | RELAXABLE, {{regr,16}, {d17,0}}},  \
+  /* opc12 r disps33 */                                                      \
+  {NAME,  3, OPC2,  20, INS_TYPE | RELAXABLE, {{regr,16}, {d33,0}}}
+
+  BR_INST ("bal",   0x307, 0x317, 0),
+
+  /* Decrement and Branch instructions */
+  BR_INST ("dbnzb", 0x304, 0x314, DCR_BRANCH_INS),
+  BR_INST ("dbnzw", 0x305, 0x315, DCR_BRANCH_INS),
+  BR_INST ("dbnzd", 0x306, 0x316, DCR_BRANCH_INS),
+
+  /* Jump and link instructions */
+  REG1_INST ("jal",    0xFF8),
+  REG2_INST ("jal",    0x37),
+  REG2_INST ("jalid",  0x33),
+
+  /* opc12 c4 opc12 r mask16 */
+  {"loadmcr", 3, 0x3110300, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}},
+  {"stormcr", 3, 0x3110301, 4, COP_REG_INS | REG_LIST | FMT_5, {{i4,16}, {regr,0}, {i16,0}}},
+
+  /* esc16 r procreg */
+  {"mtpr",    2, 0x3009,  16, 0, {{regr8,8}, {regr8,0}}},
+  /* esc16 procreg r */
+  {"mfpr",    2, 0x300A,  16, 0, {{regr8,8}, {regr8,0}}},
+  /* opc12 c4 opc8 r copreg */
+  {"mtcr",    2, 0x301030,  8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copregr,0}}},
+  /* opc12 c4 opc8 copreg r */
+  {"mfcr",    2, 0x301031,  8, COP_REG_INS | FMT_2, {{i4,16}, {copregr,4}, {regr,0}}},
+  /* opc12 c4 opc8 r copsreg */
+  {"mtcsr",   2, 0x301032,  8, COP_REG_INS | FMT_2, {{i4,16}, {regr,4}, {copsregr,0}}},
+  /* opc12 c4 opc8 copsreg r */
+  {"mfcsr",   2, 0x301033,  8, COP_REG_INS | FMT_2, {{i4,16}, {copsregr,4}, {regr,0}}},
+
+  /* CO-processor extensions */
+  /* opc12 c4 opc4 i4 disps9 */
+  {"bcop",    2, 0x30107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d9,0}}},
+  /* opc12 c4 opc4 i4 disps25 */
+  {"bcop",    3, 0x31107, 12, COP_BRANCH_INS | FMT_4, {{i4,16}, {i4,8}, {d25,0}}},
+
+  /* opc12 i4 */
+  {"excp",    1, 0xFFF,        20, 0, {{i4,16}}},
+  /* opc28 i4 */
+  {"cinv",    2, 0x3010000, 4, 0, {{i4,0}}},
+
+  /* opc9 i5 i5 i5 r r */
+  {"ram",     2, 0x7C, 23, 0, {{i5,18}, {i5,13}, {i5,8}, {regr,4}, {regr,0}}},
+  {"rim",     2, 0x7D, 23, 0, {{i5,18}, {i5,13}, {i5,8}, {regr,4}, {regr,0}}},
+
+  /* opc9 i3 r */
+  {"rotb",    1, 0x1FB,        23, 0, {{i3,20}, {regr,16}}},
+  /* opc8 i4 r */
+  {"rotw",    1, 0xB9, 24, 0, {{i4,20}, {regr,16}}},
+  /* opc23 i5 r */
+  {"rotd",    2, 0x180478,  9, 0, {{i5,4}, {regr,0}}},
+
+  {NULL,      0, 0, 0, 0, {{0, 0}}}
+};
+
+const int crx_num_opcodes = ARRAY_SIZE (crx_instruction);
+
+/* Macro to build a reg_entry, which have an opcode image :
+   For example :
+      REG(u4, 0x84, CRX_U_REGTYPE)
+   is interpreted as :
+      {"u4",  u4, 0x84, CRX_U_REGTYPE}  */
+#define REG(NAME, N, TYPE)    {STRINGX(NAME), {NAME}, N, TYPE}
+
+const reg_entry crx_regtab[] =
+{
+/* Build a general purpose register r<N>.  */
+#define REG_R(N)    REG(CONCAT2(r,N), N, CRX_R_REGTYPE)
+
+  REG_R(0),  REG_R(1), REG_R(2),  REG_R(3),
+  REG_R(4),  REG_R(5), REG_R(6),  REG_R(7),
+  REG_R(8),  REG_R(9), REG_R(10), REG_R(11),
+  REG_R(12), REG_R(13), REG_R(14), REG_R(15),
+  REG(ra, 0xe, CRX_R_REGTYPE),
+  REG(sp, 0xf, CRX_R_REGTYPE),
+
+/* Build a user register u<N>.  */
+#define REG_U(N)    REG(CONCAT2(u,N), 0x80 + N, CRX_U_REGTYPE)
+
+  REG_U(0),  REG_U(1),  REG_U(2),  REG_U(3),
+  REG_U(4),  REG_U(5),  REG_U(6),  REG_U(7),
+  REG_U(8),  REG_U(9),  REG_U(10), REG_U(11),
+  REG_U(12), REG_U(13), REG_U(14), REG_U(15),
+  REG(ura, 0x8e, CRX_U_REGTYPE),
+  REG(usp, 0x8f, CRX_U_REGTYPE),
+
+/* Build a configuration register.  */
+#define REG_CFG(NAME, N)    REG(NAME, N, CRX_CFG_REGTYPE)
+
+  REG_CFG(hi,    0x10),
+  REG_CFG(lo,    0x11),
+  REG_CFG(uhi,   0x90),
+  REG_CFG(ulo,   0x91),
+  REG_CFG(psr,   0x12),
+  REG_CFG(cfg,   0x15),
+  REG_CFG(cpcfg, 0x16),
+  REG_CFG(ccfg,         0x1b),
+
+/* Build a mptr register.  */
+#define REG_MPTR(NAME, N)    REG(NAME, N, CRX_MTPR_REGTYPE)
+
+  REG_MPTR(intbase, 0x13),
+  REG_MPTR(isp,     0x14),
+  REG_MPTR(cen,     0x17),
+
+/* Build a pc register.  */
+#define REG_PC(NAME, N)    REG(NAME, N, CRX_PC_REGTYPE)
+
+  REG_PC(pc,  0x0)
+};
+
+const int crx_num_regs = ARRAY_SIZE (crx_regtab);
+
+const reg_entry crx_copregtab[] =
+{
+/* Build a Coprocessor register c<N>.  */
+#define REG_C(N)    REG(CONCAT2(c,N), N, CRX_C_REGTYPE)
+
+  REG_C(0),  REG_C(1), REG_C(2),  REG_C(3),
+  REG_C(4),  REG_C(5), REG_C(6),  REG_C(7),
+  REG_C(8),  REG_C(9), REG_C(10), REG_C(11),
+  REG_C(12), REG_C(13), REG_C(14), REG_C(15),
+
+/* Build a Coprocessor Special register cs<N>.  */
+#define REG_CS(N)    REG(CONCAT2(cs,N), N, CRX_CS_REGTYPE)
+
+  REG_CS(0),  REG_CS(1),  REG_CS(2),  REG_CS(3),
+  REG_CS(4),  REG_CS(5),  REG_CS(6),  REG_CS(7),
+  REG_CS(8),  REG_CS(9),  REG_CS(10), REG_CS(11),
+  REG_CS(12), REG_CS(13), REG_CS(14), REG_CS(15)
+};
+
+const int crx_num_copregs = ARRAY_SIZE (crx_copregtab);
+
+/* CRX operands table.  */
+const operand_entry crx_optab[] =
+{
+  /* Index 0 is dummy, so we can count the instruction's operands.  */
+  {0,  nullargs},  /* dummy */
+  {4,  arg_ic},    /* cst4 */
+  {8,  arg_c},     /* disps9 */
+  {3,  arg_ic},    /* i3 */
+  {4,  arg_ic},    /* i4 */
+  {5,  arg_ic},    /* i5 */
+  {8,  arg_ic},    /* i8 */
+  {12, arg_ic},    /* i12 */
+  {16, arg_ic},    /* i16 */
+  {32, arg_ic},    /* i32 */
+  {4,  arg_c},     /* d5 */
+  {8,  arg_c},     /* d9 */
+  {16, arg_c},     /* d17 */
+  {24, arg_c},     /* d25 */
+  {32, arg_c},     /* d33 */
+  {16, arg_c},     /* abs16 */
+  {32, arg_c},     /* abs32 */
+  {4,  arg_rbase}, /* rbase */
+  {4,  arg_cr},    /* rbase_cst4 */
+  {8,  arg_cr},    /* rbase_dispu8 */
+  {12, arg_cr},    /* rbase_dispu12 */
+  {16, arg_cr},    /* rbase_dispu16 */
+  {28, arg_cr},    /* rbase_dispu28 */
+  {32, arg_cr},    /* rbase_dispu32 */
+  {6,  arg_icr},   /* rbase_ridx_scl2_dispu6 */
+  {22,  arg_icr},   /* rbase_ridx_scl2_dispu22 */
+  {4,  arg_r},     /* regr */
+  {8,  arg_r},     /* regr8 */
+  {4,  arg_copr},  /* copregr */
+  {8,  arg_copr},  /* copregr8 */
+  {4,  arg_copsr}  /* copsregr */
+};
+
+/* CRX traps/interrupts.  */
+const trap_entry crx_traps[] =
+{
+  {"nmi", 1}, {"svc", 5}, {"dvz", 6}, {"flg", 7},
+  {"bpt", 8}, {"und", 10}, {"prv", 11}, {"iberr", 12}
+};
+
+const int crx_num_traps = ARRAY_SIZE (crx_traps);
+
+/* cst4 operand mapping.  */
+const cst4_entry cst4_map[] =
+{
+  {0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,-4}, {6,-1},
+  {7,7}, {8,8}, {9,16}, {10,32}, {11,20}, {12,12}, {13,48}
+};
+
+const int cst4_maps = ARRAY_SIZE (cst4_map);
diff --git a/sim/mn10300/am33-2.igen b/sim/mn10300/am33-2.igen
new file mode 100644 (file)
index 0000000..bcf68b4
--- /dev/null
@@ -0,0 +1,2285 @@
+// data cache pre-fetch:
+
+// 1111 1001 1010 0110 Rm.. 0000; dcpf (Rm)
+8.0xf9+8.0xa6+4.RN2,4.0000:D1a:::dcpf
+"dcpf"
+*am33_2
+{
+  int srcreg;
+
+  PC = cia;
+
+  srcreg = translate_rreg (SD_, RN2);
+  load_word (State.regs[srcreg]);
+}
+
+// 1111 1001 1010 0111 0000 0000; dcpf (sp)
+8.0xf9+8.0xa7+8.0x00:D1b:::dcpf
+"dcpf"
+*am33_2
+{
+  PC = cia;
+
+  load_word (SP);
+}
+
+// 1111 1011 1010 0110 Ri.. Rm.. 0000 0000; dcpf (Ri,Rm)
+8.0xfb+8.0xa6+4.RN2,4.RN0+8.0x00:D2a:::dcpf
+"dcpf"
+*am33_2
+{
+  int srci, srcm;
+
+  PC = cia;
+
+  srci = translate_rreg (SD_, RN2);
+  srcm = translate_rreg (SD_, RN0);
+
+  load_word (State.regs[srci] + State.regs[srcm]);
+}
+
+// 1111 1011 1010 0111 Rm.. 0000 IMM8; dcpf (d8,Rm)
+8.0xfb+8.0xa7+4.RN2,4.0000+8.IMM8:D2b:::dcpf
+"dcpf"
+*am33_2
+{
+  int srcreg;
+
+  PC = cia;
+
+  srcreg = translate_rreg (SD_, RN2);
+
+  load_word (State.regs[srcreg] + EXTEND8 (IMM8));
+}
+
+// 1111 1101 1010 0111 Rm.. 0000 IMM24; dcpf (d24,Rm)
+8.0xfd+8.0xa7+4.RN2,4.0000+8.IMM24A+8.IMM24B+8.IMM24C:D4a:::dcpf
+"dcpf"
+*am33_2
+{
+  int srcreg;
+
+  PC = cia;
+
+  srcreg = translate_rreg (SD_, RN2);
+
+  load_word (State.regs[srcreg] + EXTEND24 (FETCH24 (IMM24A,
+                                                    IMM24B, IMM24C)));
+}
+
+// 1111 1110 0100 0110 Rm.. 0000 IMM32; dcpf (d32,Rm)
+8.0xfe+8.0x46+4.RN2,4.0000+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5a:::dcpf
+"dcpf"
+*am33_2
+{
+  int srcreg;
+
+  PC = cia;
+
+  srcreg = translate_rreg (SD_, RN2);
+
+  load_word (State.regs[srcreg]
+            + FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D));
+}
+
+// bit operations with imm8,(abs16) addressing mode:
+
+// 1111 1110 1000 0010 ABS16 IMM8; btst imm8,(abs16)
+8.0xfe+8.0x82+8.IMM16A+8.IMM16B+8.IMM8:D3:::btst
+"btst"
+*am33_2
+{
+  PC = cia;
+  genericBtst (IMM8, FETCH16 (IMM16A, IMM16B));
+}
+
+// 1111 1110 1000 0000 ABS16 IMM8; bset imm8,(abs16)
+8.0xfe+8.0x80+8.IMM16A+8.IMM16B+8.IMM8:D3:::bset
+"bset"
+*am33_2
+{
+  unsigned32 temp;
+  int z;
+  
+  PC = cia;
+  temp = load_byte (FETCH16 (IMM16A, IMM16B));
+  z = (temp & IMM8) == 0;
+  temp |= IMM8;
+  store_byte (FETCH16 (IMM16A, IMM16B), temp);
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= (z ? PSW_Z : 0);
+}
+
+// 1111 1110 1000 0001 ABS16 IMM8; bclr imm8,(abs16)
+8.0xfe+8.0x81+8.IMM16A+8.IMM16B+8.IMM8:D3:::bclr
+"bclr"
+*am33_2
+{
+  unsigned32 temp;
+  int z;
+  
+  PC = cia;
+  temp = load_byte (FETCH16 (IMM16A, IMM16B));
+  z = (temp & IMM8) == 0;
+  temp = temp & ~(IMM8);
+  store_byte (FETCH16 (IMM16A, IMM16B), temp);
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= (z ? PSW_Z : 0);
+}
+
+// single precision fmov:
+
+// 1111 1001 0010 000X Rm.. Sn..; fmov (Rm),FSn
+8.0xf9+4.2,3.0,1.X+4.Rm,4.Sn:D1a:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X,Sn) = load_word (State.regs[reg]);
+    }
+}
+
+// 1111 1001 0010 001X Rm.. Sn..; fmov (Rm+),FSn
+8.0xf9+4.2,3.1,1.X+4.Rm,4.Sn:D1b:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X,Sn) = load_word (State.regs[reg]);
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1001 0010 010X ---- Sn..; fmov (SP),FSn
+8.0xf9+4.2,3.2,1.X+4.0,4.Sn:D1c:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      XS2FS (X,Sn) = load_word (State.regs[reg]);
+    }
+}
+
+// 1111 1001 0010 011X Rm.. Sn..; fmov Rm,FSn
+8.0xf9+4.2,3.3,1.X+4.Rm,4.Sn:D1d:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X,Sn) = State.regs[reg];
+    }
+}
+
+// 1111 1001 0011 00Y0 Sm.. Rn..; fmov FSm,(Rn)
+8.0xf9+4.3,2.0,1.Y,1.0+4.Sm,4.Rn:D1e:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg], XS2FS (Y,Sm));
+    }
+}
+
+// 1111 1001 0011 00Y1 Sm.. Rn..; fmov FSm,(Rn+)
+8.0xf9+4.3,2.0,1.Y,1.1+4.Sm,4.Rn:D1f:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg], XS2FS (Y,Sm));
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1001 0011 01Y0 Sm.. ----; fmov FSm,(SP)
+8.0xf9+4.3,2.1,1.Y,1.0+4.Sm,4.0:D1g:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_word (State.regs[reg], XS2FS (Y,Sm));
+    }
+}
+
+// 1111 1001 0011 01Y1 Sm.. Rn..; fmov FSm,Rn
+8.0xf9+4.3,2.1,1.Y,1.1+4.Sm,4.Rn:D1h:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      State.regs[reg] = XS2FS (Y,Sm);
+    }
+}
+
+// 1111 1001 0100 00YX Sm.. Sn..; fmov FSm,FSn
+8.0xf9+4.4,2.0,1.Y,1.X+4.Sm,4.Sn:D1i:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    XS2FS (X,Sn) = XS2FS (Y,Sm);
+}
+
+// 1111 1011 0010 000X Rm.. Sn.. d8; fmov (d8,Rm),FSn
+8.0xfb+4.2,3.0,1.X+4.Rm,4.Sn+8.IMM8:D2a:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X, Sn) = load_word (State.regs[reg] + EXTEND8 (IMM8));
+    }
+}
+
+// 1111 1011 0010 001X Rm.. Sn.. d8; fmov (Rm+,imm8),FSn
+8.0xfb+4.2,3.1,1.X+4.Rm,4.Sn+8.IMM8:D2b:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X, Sn) = load_word (State.regs[reg] + EXTEND8 (IMM8));
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1011 0010 010X ---- Sn.. d8; fmov (d8,SP),FSn
+8.0xfb+4.2,3.2,1.X+4.0,4.Sn+8.IMM8:D2c:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      XS2FS (X, Sn) = load_word (State.regs[reg] + IMM8);
+    }
+}
+
+// 1111 1011 0010 0111 Ri.. Rm.. Sn.. --Z-; fmov (Ri,Rm),FSn
+8.0xfb+8.0x27+4.Ri,4.Rm+4.Sn,2.0,1.Z,1.0:D2d:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int ri = translate_rreg (SD_, Ri);
+      int rm = translate_rreg (SD_, Rm);
+      XS2FS (Z, Sn) = load_word (State.regs[ri] + State.regs[rm]);
+    }
+}
+
+// 1111 1011 0011 00Y0 Sm.. Rn.. d8; fmov FSm,(d8,Rn)
+8.0xfb+4.3,2.0,1.Y,1.0+4.Sm,4.Rn+8.IMM8:D2e:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg] + EXTEND8 (IMM8), XS2FS (Y, Sm));
+    }
+}
+
+// 1111 1011 0011 00Y1 Sm.. Rn.. d8; fmov FSm,(Rn+,d8)
+8.0xfb+4.3,2.0,1.Y,1.1+4.Sm,4.Rn+8.IMM8:D2f:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg] + EXTEND8 (IMM8), XS2FS (Y, Sm));
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1011 0011 01Y0 Sm.. ---- d8; fmov FSm,(d8,SP)
+8.0xfb+4.3,2.1,1.Y,1.0+4.Sm,4.0+8.IMM8:D2g:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_word (State.regs[reg] + IMM8, XS2FS (Y, Sm));
+    }
+}
+
+// 1111 1011 0011 0111 Ri.. Rm.. Sm.. --Z-; fmov FSm,(Ri,Rm)
+8.0xfb+8.0x37+4.Ri,4.Rm+4.Sm,2.0,1.Z,1.0:D2h:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int ri = translate_rreg (SD_, Ri);
+      int rm = translate_rreg (SD_, Rm);
+      store_word (State.regs[ri] + State.regs[rm], XS2FS (Z, Sm));
+    }
+}
+
+// 1111 1101 0010 000X Rm.. Sn.. d24; fmov (d24,Rm),FSn
+8.0xfd+4.2,3.0,1.X+4.Rm,4.Sn+8.IMM24A+8.IMM24B+8.IMM24C:D4a:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X, Sn) = load_word (State.regs[reg]
+                                + EXTEND24 (FETCH24 (IMM24A,
+                                                     IMM24B, IMM24C)));
+    }
+}
+
+// 1111 1101 0010 001X Rm.. Sn.. d24; fmov (Rm+,imm24),FSn
+8.0xfd+4.2,3.1,1.X+4.Rm,4.Sn+8.IMM24A+8.IMM24B+8.IMM24C:D4b:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X, Sn) = load_word (State.regs[reg]
+                                + EXTEND24 (FETCH24 (IMM24A,
+                                                     IMM24B, IMM24C)));
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1101 0010 010X ---- Sn.. d24; fmov (d24,SP),FSn
+8.0xfd+4.2,3.2,1.X+4.0,4.Sn+8.IMM24A+8.IMM24B+8.IMM24C:D4c:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      XS2FS (X, Sn) = load_word (State.regs[reg] + FETCH24 (IMM24A,
+                                                           IMM24B, IMM24C));
+    }
+}
+
+// 1111 1101 0011 00Y0 Sm.. Rn.. d24; fmov FSm,(d24,Rn)
+8.0xfd+4.3,2.0,1.Y,1.0+4.Sm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4e:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg]
+                 + EXTEND24 (FETCH24 (IMM24A,
+                                      IMM24B, IMM24C)), XS2FS (Y, Sm));
+    }
+}
+
+// 1111 1101 0011 00Y1 Sm.. Rn.. d24; fmov FSm,(Rn+,d24)
+8.0xfd+4.3,2.0,1.Y,1.1+4.Sm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4f:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg]
+                 + EXTEND24 (FETCH24 (IMM24A,
+                                      IMM24B, IMM24C)), XS2FS (Y, Sm));
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1101 0011 01Y0 Sm.. ---- d24; fmov FSm,(d24,SP)
+8.0xfd+4.3,2.1,1.Y,1.0+4.Sm,4.0+8.IMM24A+8.IMM24B+8.IMM24C:D4g:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_word (State.regs[reg]
+                 + FETCH24 (IMM24A,
+                            IMM24B, IMM24C), XS2FS (Y, Sm));
+    }
+}
+
+// 1111 1110 0010 000X Rm.. Sn.. d32; fmov (d32,Rm),FSn
+8.0xfe+4.2,3.0,1.X+4.Rm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5a:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X, Sn) = load_word (State.regs[reg]
+                                + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                                     IMM32C, IMM32D)));
+    }
+}
+
+// 1111 1110 0010 001X Rm.. Sn.. d32; fmov (Rm+,imm32),FSn
+8.0xfe+4.2,3.1,1.X+4.Rm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5b:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      XS2FS (X, Sn) = load_word (State.regs[reg]
+                                + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                                     IMM32C, IMM32D)));
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1110 0010 010X ---- Sn.. d32; fmov (d32,SP),FSn
+8.0xfe+4.2,3.2,1.X+4.0,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5c:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      XS2FS (X, Sn) = load_word (State.regs[reg]
+                                + FETCH32 (IMM32A, IMM32B,
+                                           IMM32C, IMM32D));
+    }
+}
+
+// 1111 1110 0010 011X ---- Sn.. d32; fmov imm32,FSn
+8.0xfe+4.2,3.3,1.X+4.0,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5d:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    XS2FS (X, Sn) = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+}
+
+// 1111 1110 0011 00Y0 Sm.. Rn.. d32; fmov FSm,(d32,Rn)
+8.0xfe+4.3,2.0,1.Y,1.0+4.Sm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5e:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg]
+                 + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                      IMM32C, IMM32D)), XS2FS (Y, Sm));
+    }
+}
+
+// 1111 1110 0011 00Y1 Sm.. Rn.. d32; fmov FSm,(Rn+,d32)
+8.0xfe+4.3,2.0,1.Y,1.1+4.Sm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5f:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_word (State.regs[reg]
+                 + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                      IMM32C, IMM32D)), XS2FS (Y, Sm));
+      State.regs[reg] += 4;
+    }
+}
+
+// 1111 1110 0011 01Y0 Sm.. ---- d32; fmov FSm,(d32,SP)
+8.0xfe+4.3,2.1,1.Y,1.0+4.Sm,4.0+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5g:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_word (State.regs[reg]
+                 + FETCH32 (IMM32A, IMM32B,
+                            IMM32C, IMM32D), XS2FS (Y, Sm));
+    }
+}
+
+// double precision fmov:
+
+// 1111 1001 1010 000X Rm.. fn.-; fmov (Rm),FDn
+8.0xf9+4.0xa,3.0,1.X+4.Rm,3.fn,1.0:D1j:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X,fn) = load_dword (State.regs[reg]);
+    }
+}
+
+// 1111 1001 1010 001X Rm.. fn.-; fmov (Rm+),FDn
+8.0xf9+4.0xa,3.1,1.X+4.Rm,3.fn,1.0:D1k:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X,fn) = load_dword (State.regs[reg]);
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1001 1010 010X ---- fn.-; fmov (SP),FDn
+8.0xf9+4.0xa,3.2,1.X+4.0,3.fn,1.0:D1l:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      Xf2FD (X,fn) = load_dword (State.regs[reg]);
+    }
+}
+
+// 1111 1001 1011 00Y0 fm.- Rn..; fmov FDm,(Rn)
+8.0xf9+4.0xb,2.0,1.Y,1.0+3.fm,1.0,4.Rn:D1m:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg], Xf2FD (Y,fm));
+    }
+}
+
+// 1111 1001 1011 00Y1 fm.- Rn..; fmov FDm,(Rn+)
+8.0xf9+4.0xb,2.0,1.Y,1.1+3.fm,1.0,4.Rn:D1n:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg], Xf2FD (Y,fm));
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1001 1011 01Y0 fm.- ----; fmov FDm,(SP)
+8.0xf9+4.0xb,2.1,1.Y,1.0+3.fm,1.0,4.0:D1o:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_dword (State.regs[reg], Xf2FD (Y,fm));
+    }
+}
+
+// 1111 1001 1100 00YX fm.- fn.-; fmov FDm,FDn
+8.0xf9+4.0xc,2.0,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1p:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0111 Ri.. Rm.. fn.- --Z-; fmov (Ri,Rm),FDn
+8.0xfb+8.0x47+4.Ri,4.Rm+3.fn,1.0,2.0,1.Z,1.0:D2i:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int ri = translate_rreg (SD_, Ri);
+      int rm = translate_rreg (SD_, Rm);
+      Xf2FD (Z,fn) = load_dword (State.regs[ri] + State.regs[rm]);
+    }
+}
+      
+// 1111 1011 0101 0111 Ri.. Rn.. fm.- --Z-; fmov FDm,(Ri,Rn)
+8.0xfb+8.0x57+4.Ri,4.Rn+3.fm,1.0,2.0,1.Z,1.0:D2j:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int ri = translate_rreg (SD_, Ri);
+      int rn = translate_rreg (SD_, Rn);
+      store_dword (State.regs[ri] + State.regs[rn], Xf2FD (Z,fm));
+    }
+}
+      
+// 1111 1011 1010 000X Rm.. fn.- d8; fmov (d8,Rm),FDn
+8.0xfb+4.0xa,3.0,1.X+4.Rm,4.fn+8.IMM8:D2k:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X, fn) = load_dword (State.regs[reg] + EXTEND8 (IMM8));
+    }
+}
+
+// 1111 1011 1010 001X Rm.. fn.- d8; fmov (Rm+,imm8),FDn
+8.0xfb+4.0xa,3.1,1.X+4.Rm,4.fn+8.IMM8:D2l:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X, fn) = load_dword (State.regs[reg] + EXTEND8 (IMM8));
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1011 1010 010X ---- fn.- d8; fmov (d8,SP),FDn
+8.0xfb+4.0xa,3.2,1.X+4.0,4.fn+8.IMM8:D2m:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      Xf2FD (X, fn) = load_dword (State.regs[reg] + IMM8);
+    }
+}
+
+// 1111 1011 1011 00Y0 fm.- Rn.. d8; fmov FDm,(d8,Rn)
+8.0xfb+4.0xb,2.0,1.Y,1.0+4.fm,4.Rn+8.IMM8:D2n:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg] + EXTEND8 (IMM8), Xf2FD (Y, fm));
+    }
+}
+
+// 1111 1011 1011 00Y1 fm.- Rn.. d8; fmov FDm,(Rn+,d8)
+8.0xfb+4.0xb,2.0,1.Y,1.1+4.fm,4.Rn+8.IMM8:D2o:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg] + EXTEND8 (IMM8), Xf2FD (Y, fm));
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1011 1011 01Y0 fm.- ---- d8; fmov FDm,(d8,SP)
+8.0xfb+4.0xb,2.1,1.Y,1.0+4.fm,4.0+8.IMM8:D2p:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_dword (State.regs[reg] + IMM8, Xf2FD (Y, fm));
+    }
+}
+
+// 1111 1101 1010 000X Rm.. fn.- d24; fmov (d24,Rm),FDn
+8.0xfd+4.0xa,3.0,1.X+4.Rm,4.fn+8.IMM24A+8.IMM24B+8.IMM24C:D4k:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X, fn) = load_dword (State.regs[reg]
+                                 + EXTEND24 (FETCH24 (IMM24A,
+                                                      IMM24B, IMM24C)));
+    }
+}
+
+// 1111 1101 1010 001X Rm.. fn.- d24; fmov (Rm+,imm24),FDn
+8.0xfd+4.0xa,3.1,1.X+4.Rm,4.fn+8.IMM24A+8.IMM24B+8.IMM24C:D4l:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X, fn) = load_dword (State.regs[reg]
+                                 + EXTEND24 (FETCH24 (IMM24A,
+                                                      IMM24B, IMM24C)));
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1101 1010 010X ---- fn.- d24; fmov (d24,SP),FDn
+8.0xfd+4.0xa,3.2,1.X+4.0,4.fn+8.IMM24A+8.IMM24B+8.IMM24C:D4m:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      Xf2FD (X, fn) = load_dword (State.regs[reg]
+                                 + FETCH24 (IMM24A,
+                                            IMM24B, IMM24C));
+    }
+}
+
+// 1111 1101 1011 00Y0 fm.- Rn.. d24; fmov FDm,(d24,Rn)
+8.0xfd+4.0xb,2.0,1.Y,1.0+4.fm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4n:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg]
+                  + EXTEND24 (FETCH24 (IMM24A,
+                                       IMM24B, IMM24C)), Xf2FD (Y, fm));
+    }
+}
+
+// 1111 1101 1011 00Y1 fm.- Rn.. d24; fmov FDm,(Rn+,d24)
+8.0xfd+4.0xb,2.0,1.Y,1.1+4.fm,4.Rn+8.IMM24A+8.IMM24B+8.IMM24C:D4o:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg]
+                  + EXTEND24 (FETCH24 (IMM24A,
+                                       IMM24B, IMM24C)), Xf2FD (Y, fm));
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1101 1011 01Y0 fm.- ---- d24; fmov FDm,(d24,SP)
+8.0xfd+4.0xb,2.1,1.Y,1.0+4.fm,4.0+8.IMM24A+8.IMM24B+8.IMM24C:D4p:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_dword (State.regs[reg] + FETCH24 (IMM24A,
+                                             IMM24B, IMM24C), Xf2FD (Y, fm));
+    }
+}
+
+// 1111 1110 1010 000X Rm.. fn.- d32; fmov (d32,Rm),FDn
+8.0xfe+4.0xa,3.0,1.X+4.Rm,4.fn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5k:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X, fn) = load_dword (State.regs[reg]
+                                 + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                                      IMM32C, IMM32D)));
+    }
+}
+
+// 1111 1110 1010 001X Rm.. fn.- d32; fmov (Rm+,imm32),FDn
+8.0xfe+4.0xa,3.1,1.X+4.Rm,4.fn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5l:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      Xf2FD (X, fn) = load_dword (State.regs[reg]
+                                 + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                                      IMM32C, IMM32D)));
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1110 1010 010X ---- fn.- d32; fmov (d32,SP),FDn
+8.0xfe+4.0xa,3.2,1.X+4.0,4.fn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5m:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      Xf2FD (X, fn) = load_dword (State.regs[reg]
+                                 + FETCH32 (IMM32A, IMM32B,
+                                            IMM32C, IMM32D));
+    }
+}
+
+// 1111 1110 1011 00Y0 fm.- Rn.. d32; fmov FDm,(d32,Rn)
+8.0xfe+4.0xb,2.0,1.Y,1.0+4.fm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5n:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg]
+                  + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                       IMM32C, IMM32D)), Xf2FD (Y, fm));
+    }
+}
+
+// 1111 1110 1011 00Y1 fm.- Rn.. d32; fmov FDm,(Rn+,d32)
+8.0xfe+4.0xb,2.0,1.Y,1.1+4.fm,4.Rn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5o:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      store_dword (State.regs[reg]
+                  + EXTEND32 (FETCH32 (IMM32A, IMM32B,
+                                       IMM32C, IMM32D)), Xf2FD (Y, fm));
+      State.regs[reg] += 8;
+    }
+}
+
+// 1111 1110 1011 01Y0 fm.- ---- d32; fmov FDm,(d32,SP)
+8.0xfe+4.0xb,2.1,1.Y,1.0+4.fm,4.0+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5p:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = REG_SP;
+      store_dword (State.regs[reg]
+                  + FETCH32 (IMM32A, IMM32B,
+                             IMM32C, IMM32D), Xf2FD (Y, fm));
+    }
+}
+
+// FPCR fmov:
+
+// 1111 1001 1011 0101 Rm.. ----; fmov Rm,FPCR
+8.0xf9+8.0xb5+4.Rm,4.0:D1q:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rm);
+      unsigned32 val = State.regs[reg];
+      FPCR = (val & (EC_MASK | EE_MASK | FCC_MASK))
+       | ((FPCR & ~val) & EF_MASK);
+    }
+}
+
+// 1111 1001 1011 0111 ---- Rn..; fmov FPCR,Rn
+8.0xf9+8.0xb7+4.0,4.Rn:D1r:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      int reg = translate_rreg (SD_, Rn);
+      State.regs[reg] = FPCR & FPCR_MASK;
+    }
+}
+
+// 1111 1101 1011 0101 imm32; fmov imm32,FPCR
+8.0xfd+8.0xb5+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fmov
+"fmov"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      unsigned32 val = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+      FPCR = (val & (EC_MASK | EE_MASK | FCC_MASK))
+       | ((FPCR & ~val) & EF_MASK);
+    }
+}
+
+// fabs:
+
+// 1111 1001 0100 010X ---- Sn..; fabs FSn
+8.0xf9+4.4,3.2,1.X+4.0,4.Sn:D1a:::fabs
+"fabs"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      sim_fpu in, out;
+
+      FS2FPU (XS2FS (X,Sn), in);
+      sim_fpu_abs (&out, &in);
+      FPU2FS (out, XS2FS (X,Sn));
+    }
+}
+
+// 1111 1001 1100 010X ---- Sn..; fabs FDn
+8.0xf9+4.0xc,3.2,1.X+4.0,3.fn,1.0:D1b:::fabs
+"fabs"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0100 Sm.. ---- Sn.. X-Z-; fabs FSm,FSn
+8.0xfb+8.0x44+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::fabs
+"fabs"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      sim_fpu in, out;
+
+      FS2FPU (XS2FS (X,Sm), in);
+      sim_fpu_abs (&out, &in);
+      FPU2FS (out, XS2FS (Z,Sn));
+    }
+}
+
+// 1111 1011 1100 0100 fm.- ---- fn.- X-Z-; fabs FDm,FDn
+8.0xfb+8.0xc4+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::fabs
+"fabs"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0100 011X ---- Sn..; fneg FSn
+8.0xf9+4.4,3.3,1.X+4.0,4.Sn:D1a:::fneg
+"fneg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      sim_fpu in, out;
+
+      FS2FPU (XS2FS (X,Sn), in);
+      sim_fpu_neg (&out, &in);
+      FPU2FS (out, XS2FS (X,Sn));
+    }
+}
+
+// 1111 1001 1100 011X ---- Sn..; fneg FDn
+8.0xf9+4.0xc,3.3,1.X+4.0,3.fn,1.0:D1b:::fneg
+"fneg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0110 Sm.. ---- Sn.. X-Z-; fneg FSm,FSn
+8.0xfb+8.0x46+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::fneg
+"fneg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      sim_fpu in, out;
+
+      FS2FPU (XS2FS (X,Sm), in);
+      sim_fpu_neg (&out, &in);
+      FPU2FS (out, XS2FS (Z,Sn));
+    }
+}
+
+// 1111 1011 1100 0110 fm.- ---- fn.- X-Z-; fneg FDm,FDn
+8.0xfb+8.0xc6+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::fneg
+"fneg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0101 000X ---- Sn..; frsqrt FSn
+8.0xf9+4.5,3.0,1.X+4.0,4.Sn:D1a:::frsqrt
+"frsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_rsqrt (SD, CPU, cia, &XS2FS (X,Sn), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1101 000X ---- fn.-; frsqrt FDn
+8.0xf9+4.0xd,3.0,1.X+4.0,3.fn,1.0:D1b:::frsqrt
+"frsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0000 Sm.. ---- Sn.. X-Z-; frsqrt FSm,FSn
+8.0xfb+8.0x50+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::frsqrt
+"frsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_rsqrt (SD, CPU, cia, &XS2FS (X,Sm), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1101 0000 fm.- ---- fn.- X-Z-; frsqrt FDm,FDn
+8.0xfb+8.0xd0+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::frsqrt
+"frsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0101 001X ---- Sn..; fsqrt FSn
+8.0xf9+4.5,3.1,1.X+4.0,4.Sn:D1a:::fsqrt
+"fsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 1101 001X ---- fn.-; fsqrt FDn
+8.0xf9+4.0xd,3.1,1.X+4.0,3.fn,1.0:D1b:::fsqrt
+"fsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0100 Sm.. ---- Sn.. X-Z-; fsqrt FSm,FSn
+8.0xfb+8.0x54+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2a:::fsqrt
+"fsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 1101 0100 fm.- ---- fn.- X-Z-; fsqrt FDm,FDn
+8.0xfb+8.0xd4+3.fm,1.0,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2b:::fsqrt
+"fsqrt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1001 0101 01YX Sm.. Sn..; fcmp FSm, FSn
+8.0xf9+4.5,2.1,1.Y,1.X+4.Sm,4.Sn:D1a:::fcmp
+"fcmp"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_cmp (SD, CPU, cia, &XS2FS (X,Sn), &XS2FS (Y,Sm), FP_SINGLE);
+}
+
+// 1111 1001 1101 01YX fm.- fn.-; fcmp FDm, FDn
+8.0xf9+4.0xd,2.1,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fcmp
+"fcmp"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1110 0011 01Y1 Sm.. ---- IMM32; fcmp imm32, FSm
+8.0xfe+4.3,2.1,1.Y,1.1+4.Sm,4.0+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fcmp
+"fcmp"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+      fpu_cmp (SD, CPU, cia, &XS2FS (Y,Sm), &imm, FP_SINGLE);
+    }
+}
+
+// 1111 1001 0110 00YX Sm.. Sn..; fadd FSm, FSn
+8.0xf9+4.6,2.0,1.Y,1.X+4.Sm,4.Sn:D1a:::fadd
+"fadd"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_add (SD, CPU, cia,
+            &XS2FS (Y,Sm), &XS2FS (X,Sn), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1110 00YX fm.- fn.-; fadd FDm, FDn
+8.0xf9+4.0xe,2.0,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fadd
+"fadd"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0110 0000 Sm1. Sm2. Sn.. XYZ-; fadd FSm1, FSm2, FSn
+8.0xfb+8.0x60+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fadd
+"fadd"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_add (SD, CPU, cia,
+            &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1110 0000 fm1- fm2- fn.- XYZ-; fadd FDm1, FDm2, FDn
+8.0xfb+8.0xe0+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fadd
+"fadd"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0110 00YX Sm.. Sn.. IMM32; fadd imm32, FSm, FSn
+8.0xfe+4.6,2.0,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fadd
+"fadd"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+      fpu_add (SD, CPU, cia,
+              &XS2FS (Y,Sm), &imm, &XS2FS (X,Sn), FP_SINGLE);
+    }
+}
+
+// 1111 1001 0110 01YX Sm.. Sn..; fsub FSm, FSn
+8.0xf9+4.6,2.1,1.Y,1.X+4.Sm,4.Sn:D1a:::fsub
+"fsub"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_sub (SD, CPU, cia,
+            &XS2FS (X,Sn), &XS2FS (Y,Sm), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1110 01YX fm.- fn.-; fsub FDm, FDn
+8.0xf9+4.0xe,2.1,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fsub
+"fsub"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0110 0100 Sm1. Sm2. Sn.. XYZ-; fsub FSm1, FSm2, FSn
+8.0xfb+8.0x64+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fsub
+"fsub"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_sub (SD, CPU, cia,
+            &XS2FS (Y,Sm2), &XS2FS (X,Sm1), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1110 0100 fm1- fm2- fn.- XYZ-; fsub FDm1, FDm2, FDn
+8.0xfb+8.0xe4+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fsub
+"fsub"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0110 01YX Sm.. Sn.. IMM32; fsub imm32, FSm, FSn
+8.0xfe+4.6,2.1,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fsub
+"fsub"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+      fpu_sub (SD, CPU, cia,
+              &XS2FS (Y,Sm), &imm, &XS2FS (X,Sn), FP_SINGLE);
+    }
+}
+
+// 1111 1001 0111 00YX Sm.. Sn..; fmul FSm, FSn
+8.0xf9+4.7,2.0,1.Y,1.X+4.Sm,4.Sn:D1a:::fmul
+"fmul"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_mul (SD, CPU, cia,
+            &XS2FS (Y,Sm), &XS2FS (X,Sn), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1111 00YX fm.- fn.-; fmul FDm, FDn
+8.0xf9+4.0xf,2.0,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fmul
+"fmul"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0111 0000 Sm1. Sm2. Sn.. XYZ-; fmul FSm1, FSm2, FSn
+8.0xfb+8.0x70+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fmul
+"fmul"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_mul (SD, CPU, cia,
+            &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1111 0000 fm1- fm2- fn.- XYZ-; fmul FDm1, FDm2, FDn
+8.0xfb+8.0xf0+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fmul
+"fmul"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0111 00YX Sm.. Sn.. IMM32; fmul imm32, FSm, FSn
+8.0xfe+4.7,2.0,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fmul
+"fmul"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+      fpu_mul (SD, CPU, cia,
+              &imm, &XS2FS (Y,Sm), &XS2FS (X,Sn), FP_SINGLE);
+    }
+}
+
+// 1111 1001 0111 01YX Sm.. Sn..; fdiv FSm, FSn
+8.0xf9+4.7,2.1,1.Y,1.X+4.Sm,4.Sn:D1a:::fdiv
+"fdiv"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_div (SD, CPU, cia,
+            &XS2FS (X,Sn), &XS2FS (Y,Sm), &XS2FS (X,Sn), FP_SINGLE);
+}
+
+// 1111 1001 1111 01YX fm.- fn.-; fdiv FDm, FDn
+8.0xf9+4.0xf,2.1,1.Y,1.X+3.fm,1.0,3.fn,1.0:D1b:::fdiv
+"fdiv"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0111 0100 Sm1. Sm2. Sn.. XYZ-; fdiv FSm1, FSm2, FSn
+8.0xfb+8.0x74+4.Sm1,4.Sm2+4.Sn,1.X,1.Y,1.Z,1.0:D2a:::fdiv
+"fdiv"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_div (SD, CPU, cia,
+            &XS2FS (Y,Sm2), &XS2FS (X,Sm1), &XS2FS (Z,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1111 0100 fm1- fm2- fn.- XYZ-; fdiv FDm1, FDm2, FDn
+8.0xfb+8.0xf4+3.fm1,1.0,3.fm2,1.0+3.fn,1.0,1.X,1.Y,1.Z,1.0:D2b:::fdiv
+"fdiv"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+
+// 1111 1110 0111 01YX Sm.. Sn.. IMM32; fdiv imm32, FSm, FSn
+8.0xfe+4.7,2.1,1.Y,1.X+4.Sm,4.Sn+8.IMM32A+8.IMM32B+8.IMM32C+8.IMM32D:D5:::fdiv
+"fdiv"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    {
+      uint32 imm = FETCH32 (IMM32A, IMM32B, IMM32C, IMM32D);
+
+      fpu_div (SD, CPU, cia,
+              &XS2FS (Y,Sm), &imm, &XS2FS (X,Sn), FP_SINGLE);
+    }
+}
+
+// 1111 1011 1000 00Sn Sm1. Sm2. Sm3. XYZA; fmadd FSm1, FSm2, FSm3, FSn
+8.0xfb+4.8,2.0,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fmadd
+"fmadd"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_fmadd (SD, CPU, cia,
+              &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+              &AS2FS (A,Sn), FP_SINGLE);
+}
+    
+// 1111 1011 1000 01Sn Sm1. Sm2. Sm3. XYZA; fmsub FSm1, FSm2, FSm3, FSn
+8.0xfb+4.8,2.1,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fmsub
+"fmsub"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_fmsub (SD, CPU, cia,
+              &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+              &AS2FS (A,Sn), FP_SINGLE);
+}
+
+// 1111 1011 1001 00Sn Sm1. Sm2. Sm3. XYZA; fnmadd FSm1, FSm2, FSm3, FSn
+8.0xfb+4.9,2.0,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fnmadd
+"fnmadd"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_fnmadd (SD, CPU, cia,
+               &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+               &AS2FS (A,Sn), FP_SINGLE);
+}
+    
+// 1111 1011 1001 01Sn Sm1. Sm2. Sm3. XYZA; fnmsub FSm1, FSm2, FSm3, FSn
+8.0xfb+4.9,2.1,2.Sn+4.Sm1,4.Sm2+4.Sm3,1.X,1.Y,1.Z,1.A:D2:::fnmsub
+"fnmsub"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_fnmsub (SD, CPU, cia,
+               &XS2FS (X,Sm1), &XS2FS (Y,Sm2), &XS2FS (Z,Sm3),
+               &AS2FS (A,Sn), FP_SINGLE);
+}
+
+// conversion:
+
+// 1111 1011 0100 0000 Sm.. ---- Sn.. X-Z-; ftoi FSm,FSn
+8.0xfb+8.0x40+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2:::ftoi
+"ftoi"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0100 0010 Sm.. ---- Sn.. X-Z-; itof FSm,FSn
+8.0xfb+8.0x42+4.Sm,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2:::itof
+"itof"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0010 Sm.. ---- fn.- X-Z-; ftod FSm,FDn
+8.0xfb+8.0x52+4.Sm,4.0+3.fn,1.0,1.X,1.0,1.Z,1.0:D2:::ftod
+"ftod"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// 1111 1011 0101 0110 fm.- ---- Sn.. X-Z-; dtof FDm,FSn
+8.0xfb+8.0x56+3.fm,1.0,4.0+4.Sn,1.X,1.0,1.Z,1.0:D2:::dtof
+"dtof"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else
+    fpu_unimp_exception (SD, CPU, cia);
+}
+
+// branching:
+
+// 1111 1000 1101 0000 d8; fbeq (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd0+8.D8:D1:::fbeq
+"fbeq"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_E))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 0001 d8; fbne (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd1+8.D8:D1:::fbne
+"fbne"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_L | FCC_G)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 0010 d8; fbgt (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd2+8.D8:D1:::fbgt
+"fbgt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_G))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 0011 d8; fbge (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd3+8.D8:D1:::fbge
+"fbge"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_G | FCC_E)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 0100 d8; fblt (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd4+8.D8:D1:::fblt
+"fblt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_L))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 0101 d8; fble (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd5+8.D8:D1:::fble
+"fble"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_L | FCC_E)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 0110 d8; fbuo (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd6+8.D8:D1:::fbuo
+"fbuo"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_U))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 0111 d8; fblg (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd7+8.D8:D1:::fblg
+"fblg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_L | FCC_G)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+// 1111 1000 1101 1000 d8; fbleg (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd8+8.D8:D1:::fbleg
+"fbleg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_L | FCC_E | FCC_G)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 1001 d8; fbug (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xd9+8.D8:D1:::fbug
+"fbug"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_G)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 1010 d8; fbuge (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xda+8.D8:D1:::fbuge
+"fbuge"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_G | FCC_E)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 1011 d8; fbul (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xdb+8.D8:D1:::fbul
+"fbul"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_L)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 1100 d8; fbule (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xdc+8.D8:D1:::fbule
+"fbule"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_L | FCC_E)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 1000 1101 1101 d8; fbue (d8,PC) (d8 is sign-extended)
+8.0xf8+8.0xdd+8.D8:D1:::fbue
+"fbue"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_E)))
+    {
+      State.regs[REG_PC] += EXTEND8 (D8);
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0000; fleq
+8.0xf0+8.0xd0:D0:::fleq
+"fleq"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_E))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0001; flne
+8.0xf0+8.0xd1:D0:::flne
+"flne"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_L | FCC_G)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0010; flgt
+8.0xf0+8.0xd2:D0:::flgt
+"flgt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_G))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0011; flge
+8.0xf0+8.0xd3:D0:::flge
+"flge"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_G | FCC_E)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0100; fllt
+8.0xf0+8.0xd4:D0:::fllt
+"fllt"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_L))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0101; flle
+8.0xf0+8.0xd5:D0:::flle
+"flle"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_L | FCC_E)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0110; fluo
+8.0xf0+8.0xd6:D0:::fluo
+"fluo"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & FCC_U))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 0111; fllg
+8.0xf0+8.0xd7:D0:::fllg
+"fllg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_L | FCC_G)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+// 1111 0000 1101 1000; flleg
+8.0xf0+8.0xd8:D0:::flleg
+"flleg"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_L | FCC_E | FCC_G)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 1001; flug
+8.0xf0+8.0xd9:D0:::flug
+"flug"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_G)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 1010; fluge
+8.0xf0+8.0xda:D0:::fluge
+"fluge"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_G | FCC_E)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 1011; flul
+8.0xf0+8.0xdb:D0:::flul
+"flul"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_L)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 1100; flule
+8.0xf0+8.0xdc:D0:::flule
+"flule"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_L | FCC_E)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
+
+// 1111 0000 1101 1101; flue
+8.0xf0+8.0xdd:D0:::flue
+"flue"
+*am33_2
+{
+  PC = cia;
+
+  if (FPU_DISABLED)
+    fpu_disabled_exception (SD, CPU, cia);
+  else if ((FPCR & (FCC_U | FCC_E)))
+    {
+      State.regs[REG_PC] = State.regs[REG_LAR] - 4;
+      nia = PC;
+    }
+}
diff --git a/sim/ppc/gdb-sim.c b/sim/ppc/gdb-sim.c
new file mode 100644 (file)
index 0000000..648d8ef
--- /dev/null
@@ -0,0 +1,1295 @@
+/*  This file is part of GDB.
+
+    Copyright 2004 Free Software Foundation, Inc.
+
+    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.
+    */
+
+
+#include "psim.h"
+#include "options.h"
+#include "registers.h"
+
+#include "ansidecl.h"
+#include "sim_callbacks.h"
+#include "gdb/callback.h"
+#include "gdb/remote-sim.h"
+#include "gdb/sim-ppc.h"
+
+/* Return the name of the register whose number is REGNUM, or zero if
+   REGNUM is an invalid register number.  */
+
+static const char *
+regnum2spr (int spr)
+{
+  if (spr_is_valid (spr))
+    return spr_name (spr);
+  else
+    return NULL;
+}
+
+static const char *
+regnum2name (int regnum)
+{
+  switch (regnum)
+    {
+    case sim_ppc_r0_regnum: return "r0";
+    case sim_ppc_r1_regnum: return "r1";
+    case sim_ppc_r2_regnum: return "r2";
+    case sim_ppc_r3_regnum: return "r3";
+    case sim_ppc_r4_regnum: return "r4";
+    case sim_ppc_r5_regnum: return "r5";
+    case sim_ppc_r6_regnum: return "r6";
+    case sim_ppc_r7_regnum: return "r7";
+    case sim_ppc_r8_regnum: return "r8";
+    case sim_ppc_r9_regnum: return "r9";
+    case sim_ppc_r10_regnum: return "r10";
+    case sim_ppc_r11_regnum: return "r11";
+    case sim_ppc_r12_regnum: return "r12";
+    case sim_ppc_r13_regnum: return "r13";
+    case sim_ppc_r14_regnum: return "r14";
+    case sim_ppc_r15_regnum: return "r15";
+    case sim_ppc_r16_regnum: return "r16";
+    case sim_ppc_r17_regnum: return "r17";
+    case sim_ppc_r18_regnum: return "r18";
+    case sim_ppc_r19_regnum: return "r19";
+    case sim_ppc_r20_regnum: return "r20";
+    case sim_ppc_r21_regnum: return "r21";
+    case sim_ppc_r22_regnum: return "r22";
+    case sim_ppc_r23_regnum: return "r23";
+    case sim_ppc_r24_regnum: return "r24";
+    case sim_ppc_r25_regnum: return "r25";
+    case sim_ppc_r26_regnum: return "r26";
+    case sim_ppc_r27_regnum: return "r27";
+    case sim_ppc_r28_regnum: return "r28";
+    case sim_ppc_r29_regnum: return "r29";
+    case sim_ppc_r30_regnum: return "r30";
+    case sim_ppc_r31_regnum: return "r31";
+
+    case sim_ppc_f0_regnum: return "f0";
+    case sim_ppc_f1_regnum: return "f1";
+    case sim_ppc_f2_regnum: return "f2";
+    case sim_ppc_f3_regnum: return "f3";
+    case sim_ppc_f4_regnum: return "f4";
+    case sim_ppc_f5_regnum: return "f5";
+    case sim_ppc_f6_regnum: return "f6";
+    case sim_ppc_f7_regnum: return "f7";
+    case sim_ppc_f8_regnum: return "f8";
+    case sim_ppc_f9_regnum: return "f9";
+    case sim_ppc_f10_regnum: return "f10";
+    case sim_ppc_f11_regnum: return "f11";
+    case sim_ppc_f12_regnum: return "f12";
+    case sim_ppc_f13_regnum: return "f13";
+    case sim_ppc_f14_regnum: return "f14";
+    case sim_ppc_f15_regnum: return "f15";
+    case sim_ppc_f16_regnum: return "f16";
+    case sim_ppc_f17_regnum: return "f17";
+    case sim_ppc_f18_regnum: return "f18";
+    case sim_ppc_f19_regnum: return "f19";
+    case sim_ppc_f20_regnum: return "f20";
+    case sim_ppc_f21_regnum: return "f21";
+    case sim_ppc_f22_regnum: return "f22";
+    case sim_ppc_f23_regnum: return "f23";
+    case sim_ppc_f24_regnum: return "f24";
+    case sim_ppc_f25_regnum: return "f25";
+    case sim_ppc_f26_regnum: return "f26";
+    case sim_ppc_f27_regnum: return "f27";
+    case sim_ppc_f28_regnum: return "f28";
+    case sim_ppc_f29_regnum: return "f29";
+    case sim_ppc_f30_regnum: return "f30";
+    case sim_ppc_f31_regnum: return "f31";
+
+    case sim_ppc_vr0_regnum: return "vr0";
+    case sim_ppc_vr1_regnum: return "vr1";
+    case sim_ppc_vr2_regnum: return "vr2";
+    case sim_ppc_vr3_regnum: return "vr3";
+    case sim_ppc_vr4_regnum: return "vr4";
+    case sim_ppc_vr5_regnum: return "vr5";
+    case sim_ppc_vr6_regnum: return "vr6";
+    case sim_ppc_vr7_regnum: return "vr7";
+    case sim_ppc_vr8_regnum: return "vr8";
+    case sim_ppc_vr9_regnum: return "vr9";
+    case sim_ppc_vr10_regnum: return "vr10";
+    case sim_ppc_vr11_regnum: return "vr11";
+    case sim_ppc_vr12_regnum: return "vr12";
+    case sim_ppc_vr13_regnum: return "vr13";
+    case sim_ppc_vr14_regnum: return "vr14";
+    case sim_ppc_vr15_regnum: return "vr15";
+    case sim_ppc_vr16_regnum: return "vr16";
+    case sim_ppc_vr17_regnum: return "vr17";
+    case sim_ppc_vr18_regnum: return "vr18";
+    case sim_ppc_vr19_regnum: return "vr19";
+    case sim_ppc_vr20_regnum: return "vr20";
+    case sim_ppc_vr21_regnum: return "vr21";
+    case sim_ppc_vr22_regnum: return "vr22";
+    case sim_ppc_vr23_regnum: return "vr23";
+    case sim_ppc_vr24_regnum: return "vr24";
+    case sim_ppc_vr25_regnum: return "vr25";
+    case sim_ppc_vr26_regnum: return "vr26";
+    case sim_ppc_vr27_regnum: return "vr27";
+    case sim_ppc_vr28_regnum: return "vr28";
+    case sim_ppc_vr29_regnum: return "vr29";
+    case sim_ppc_vr30_regnum: return "vr30";
+    case sim_ppc_vr31_regnum: return "vr31";
+    case sim_ppc_rh0_regnum: return "rh0";
+    case sim_ppc_rh1_regnum: return "rh1";
+    case sim_ppc_rh2_regnum: return "rh2";
+    case sim_ppc_rh3_regnum: return "rh3";
+    case sim_ppc_rh4_regnum: return "rh4";
+    case sim_ppc_rh5_regnum: return "rh5";
+    case sim_ppc_rh6_regnum: return "rh6";
+    case sim_ppc_rh7_regnum: return "rh7";
+    case sim_ppc_rh8_regnum: return "rh8";
+    case sim_ppc_rh9_regnum: return "rh9";
+    case sim_ppc_rh10_regnum: return "rh10";
+    case sim_ppc_rh11_regnum: return "rh11";
+    case sim_ppc_rh12_regnum: return "rh12";
+    case sim_ppc_rh13_regnum: return "rh13";
+    case sim_ppc_rh14_regnum: return "rh14";
+    case sim_ppc_rh15_regnum: return "rh15";
+    case sim_ppc_rh16_regnum: return "rh16";
+    case sim_ppc_rh17_regnum: return "rh17";
+    case sim_ppc_rh18_regnum: return "rh18";
+    case sim_ppc_rh19_regnum: return "rh19";
+    case sim_ppc_rh20_regnum: return "rh20";
+    case sim_ppc_rh21_regnum: return "rh21";
+    case sim_ppc_rh22_regnum: return "rh22";
+    case sim_ppc_rh23_regnum: return "rh23";
+    case sim_ppc_rh24_regnum: return "rh24";
+    case sim_ppc_rh25_regnum: return "rh25";
+    case sim_ppc_rh26_regnum: return "rh26";
+    case sim_ppc_rh27_regnum: return "rh27";
+    case sim_ppc_rh28_regnum: return "rh28";
+    case sim_ppc_rh29_regnum: return "rh29";
+    case sim_ppc_rh30_regnum: return "rh30";
+    case sim_ppc_rh31_regnum: return "rh31";
+
+    case sim_ppc_ev0_regnum: return "ev0";
+    case sim_ppc_ev1_regnum: return "ev1";
+    case sim_ppc_ev2_regnum: return "ev2";
+    case sim_ppc_ev3_regnum: return "ev3";
+    case sim_ppc_ev4_regnum: return "ev4";
+    case sim_ppc_ev5_regnum: return "ev5";
+    case sim_ppc_ev6_regnum: return "ev6";
+    case sim_ppc_ev7_regnum: return "ev7";
+    case sim_ppc_ev8_regnum: return "ev8";
+    case sim_ppc_ev9_regnum: return "ev9";
+    case sim_ppc_ev10_regnum: return "ev10";
+    case sim_ppc_ev11_regnum: return "ev11";
+    case sim_ppc_ev12_regnum: return "ev12";
+    case sim_ppc_ev13_regnum: return "ev13";
+    case sim_ppc_ev14_regnum: return "ev14";
+    case sim_ppc_ev15_regnum: return "ev15";
+    case sim_ppc_ev16_regnum: return "ev16";
+    case sim_ppc_ev17_regnum: return "ev17";
+    case sim_ppc_ev18_regnum: return "ev18";
+    case sim_ppc_ev19_regnum: return "ev19";
+    case sim_ppc_ev20_regnum: return "ev20";
+    case sim_ppc_ev21_regnum: return "ev21";
+    case sim_ppc_ev22_regnum: return "ev22";
+    case sim_ppc_ev23_regnum: return "ev23";
+    case sim_ppc_ev24_regnum: return "ev24";
+    case sim_ppc_ev25_regnum: return "ev25";
+    case sim_ppc_ev26_regnum: return "ev26";
+    case sim_ppc_ev27_regnum: return "ev27";
+    case sim_ppc_ev28_regnum: return "ev28";
+    case sim_ppc_ev29_regnum: return "ev29";
+    case sim_ppc_ev30_regnum: return "ev30";
+    case sim_ppc_ev31_regnum: return "ev31";
+
+    case sim_ppc_sr0_regnum: return "sr0";
+    case sim_ppc_sr1_regnum: return "sr1";
+    case sim_ppc_sr2_regnum: return "sr2";
+    case sim_ppc_sr3_regnum: return "sr3";
+    case sim_ppc_sr4_regnum: return "sr4";
+    case sim_ppc_sr5_regnum: return "sr5";
+    case sim_ppc_sr6_regnum: return "sr6";
+    case sim_ppc_sr7_regnum: return "sr7";
+    case sim_ppc_sr8_regnum: return "sr8";
+    case sim_ppc_sr9_regnum: return "sr9";
+    case sim_ppc_sr10_regnum: return "sr10";
+    case sim_ppc_sr11_regnum: return "sr11";
+    case sim_ppc_sr12_regnum: return "sr12";
+    case sim_ppc_sr13_regnum: return "sr13";
+    case sim_ppc_sr14_regnum: return "sr14";
+    case sim_ppc_sr15_regnum: return "sr15";
+
+    case sim_ppc_pc_regnum: return "pc";
+    case sim_ppc_ps_regnum: return "ps";
+    case sim_ppc_cr_regnum: return "cr";
+    case sim_ppc_fpscr_regnum: return "fpscr";
+    case sim_ppc_acc_regnum: return "acc";
+    case sim_ppc_vscr_regnum: return "vscr";
+
+    case sim_ppc_spr0_regnum: return regnum2spr (0);
+    case sim_ppc_spr1_regnum: return regnum2spr (1);
+    case sim_ppc_spr2_regnum: return regnum2spr (2);
+    case sim_ppc_spr3_regnum: return regnum2spr (3);
+    case sim_ppc_spr4_regnum: return regnum2spr (4);
+    case sim_ppc_spr5_regnum: return regnum2spr (5);
+    case sim_ppc_spr6_regnum: return regnum2spr (6);
+    case sim_ppc_spr7_regnum: return regnum2spr (7);
+    case sim_ppc_spr8_regnum: return regnum2spr (8);
+    case sim_ppc_spr9_regnum: return regnum2spr (9);
+    case sim_ppc_spr10_regnum: return regnum2spr (10);
+    case sim_ppc_spr11_regnum: return regnum2spr (11);
+    case sim_ppc_spr12_regnum: return regnum2spr (12);
+    case sim_ppc_spr13_regnum: return regnum2spr (13);
+    case sim_ppc_spr14_regnum: return regnum2spr (14);
+    case sim_ppc_spr15_regnum: return regnum2spr (15);
+    case sim_ppc_spr16_regnum: return regnum2spr (16);
+    case sim_ppc_spr17_regnum: return regnum2spr (17);
+    case sim_ppc_spr18_regnum: return regnum2spr (18);
+    case sim_ppc_spr19_regnum: return regnum2spr (19);
+    case sim_ppc_spr20_regnum: return regnum2spr (20);
+    case sim_ppc_spr21_regnum: return regnum2spr (21);
+    case sim_ppc_spr22_regnum: return regnum2spr (22);
+    case sim_ppc_spr23_regnum: return regnum2spr (23);
+    case sim_ppc_spr24_regnum: return regnum2spr (24);
+    case sim_ppc_spr25_regnum: return regnum2spr (25);
+    case sim_ppc_spr26_regnum: return regnum2spr (26);
+    case sim_ppc_spr27_regnum: return regnum2spr (27);
+    case sim_ppc_spr28_regnum: return regnum2spr (28);
+    case sim_ppc_spr29_regnum: return regnum2spr (29);
+    case sim_ppc_spr30_regnum: return regnum2spr (30);
+    case sim_ppc_spr31_regnum: return regnum2spr (31);
+    case sim_ppc_spr32_regnum: return regnum2spr (32);
+    case sim_ppc_spr33_regnum: return regnum2spr (33);
+    case sim_ppc_spr34_regnum: return regnum2spr (34);
+    case sim_ppc_spr35_regnum: return regnum2spr (35);
+    case sim_ppc_spr36_regnum: return regnum2spr (36);
+    case sim_ppc_spr37_regnum: return regnum2spr (37);
+    case sim_ppc_spr38_regnum: return regnum2spr (38);
+    case sim_ppc_spr39_regnum: return regnum2spr (39);
+    case sim_ppc_spr40_regnum: return regnum2spr (40);
+    case sim_ppc_spr41_regnum: return regnum2spr (41);
+    case sim_ppc_spr42_regnum: return regnum2spr (42);
+    case sim_ppc_spr43_regnum: return regnum2spr (43);
+    case sim_ppc_spr44_regnum: return regnum2spr (44);
+    case sim_ppc_spr45_regnum: return regnum2spr (45);
+    case sim_ppc_spr46_regnum: return regnum2spr (46);
+    case sim_ppc_spr47_regnum: return regnum2spr (47);
+    case sim_ppc_spr48_regnum: return regnum2spr (48);
+    case sim_ppc_spr49_regnum: return regnum2spr (49);
+    case sim_ppc_spr50_regnum: return regnum2spr (50);
+    case sim_ppc_spr51_regnum: return regnum2spr (51);
+    case sim_ppc_spr52_regnum: return regnum2spr (52);
+    case sim_ppc_spr53_regnum: return regnum2spr (53);
+    case sim_ppc_spr54_regnum: return regnum2spr (54);
+    case sim_ppc_spr55_regnum: return regnum2spr (55);
+    case sim_ppc_spr56_regnum: return regnum2spr (56);
+    case sim_ppc_spr57_regnum: return regnum2spr (57);
+    case sim_ppc_spr58_regnum: return regnum2spr (58);
+    case sim_ppc_spr59_regnum: return regnum2spr (59);
+    case sim_ppc_spr60_regnum: return regnum2spr (60);
+    case sim_ppc_spr61_regnum: return regnum2spr (61);
+    case sim_ppc_spr62_regnum: return regnum2spr (62);
+    case sim_ppc_spr63_regnum: return regnum2spr (63);
+    case sim_ppc_spr64_regnum: return regnum2spr (64);
+    case sim_ppc_spr65_regnum: return regnum2spr (65);
+    case sim_ppc_spr66_regnum: return regnum2spr (66);
+    case sim_ppc_spr67_regnum: return regnum2spr (67);
+    case sim_ppc_spr68_regnum: return regnum2spr (68);
+    case sim_ppc_spr69_regnum: return regnum2spr (69);
+    case sim_ppc_spr70_regnum: return regnum2spr (70);
+    case sim_ppc_spr71_regnum: return regnum2spr (71);
+    case sim_ppc_spr72_regnum: return regnum2spr (72);
+    case sim_ppc_spr73_regnum: return regnum2spr (73);
+    case sim_ppc_spr74_regnum: return regnum2spr (74);
+    case sim_ppc_spr75_regnum: return regnum2spr (75);
+    case sim_ppc_spr76_regnum: return regnum2spr (76);
+    case sim_ppc_spr77_regnum: return regnum2spr (77);
+    case sim_ppc_spr78_regnum: return regnum2spr (78);
+    case sim_ppc_spr79_regnum: return regnum2spr (79);
+    case sim_ppc_spr80_regnum: return regnum2spr (80);
+    case sim_ppc_spr81_regnum: return regnum2spr (81);
+    case sim_ppc_spr82_regnum: return regnum2spr (82);
+    case sim_ppc_spr83_regnum: return regnum2spr (83);
+    case sim_ppc_spr84_regnum: return regnum2spr (84);
+    case sim_ppc_spr85_regnum: return regnum2spr (85);
+    case sim_ppc_spr86_regnum: return regnum2spr (86);
+    case sim_ppc_spr87_regnum: return regnum2spr (87);
+    case sim_ppc_spr88_regnum: return regnum2spr (88);
+    case sim_ppc_spr89_regnum: return regnum2spr (89);
+    case sim_ppc_spr90_regnum: return regnum2spr (90);
+    case sim_ppc_spr91_regnum: return regnum2spr (91);
+    case sim_ppc_spr92_regnum: return regnum2spr (92);
+    case sim_ppc_spr93_regnum: return regnum2spr (93);
+    case sim_ppc_spr94_regnum: return regnum2spr (94);
+    case sim_ppc_spr95_regnum: return regnum2spr (95);
+    case sim_ppc_spr96_regnum: return regnum2spr (96);
+    case sim_ppc_spr97_regnum: return regnum2spr (97);
+    case sim_ppc_spr98_regnum: return regnum2spr (98);
+    case sim_ppc_spr99_regnum: return regnum2spr (99);
+    case sim_ppc_spr100_regnum: return regnum2spr (100);
+    case sim_ppc_spr101_regnum: return regnum2spr (101);
+    case sim_ppc_spr102_regnum: return regnum2spr (102);
+    case sim_ppc_spr103_regnum: return regnum2spr (103);
+    case sim_ppc_spr104_regnum: return regnum2spr (104);
+    case sim_ppc_spr105_regnum: return regnum2spr (105);
+    case sim_ppc_spr106_regnum: return regnum2spr (106);
+    case sim_ppc_spr107_regnum: return regnum2spr (107);
+    case sim_ppc_spr108_regnum: return regnum2spr (108);
+    case sim_ppc_spr109_regnum: return regnum2spr (109);
+    case sim_ppc_spr110_regnum: return regnum2spr (110);
+    case sim_ppc_spr111_regnum: return regnum2spr (111);
+    case sim_ppc_spr112_regnum: return regnum2spr (112);
+    case sim_ppc_spr113_regnum: return regnum2spr (113);
+    case sim_ppc_spr114_regnum: return regnum2spr (114);
+    case sim_ppc_spr115_regnum: return regnum2spr (115);
+    case sim_ppc_spr116_regnum: return regnum2spr (116);
+    case sim_ppc_spr117_regnum: return regnum2spr (117);
+    case sim_ppc_spr118_regnum: return regnum2spr (118);
+    case sim_ppc_spr119_regnum: return regnum2spr (119);
+    case sim_ppc_spr120_regnum: return regnum2spr (120);
+    case sim_ppc_spr121_regnum: return regnum2spr (121);
+    case sim_ppc_spr122_regnum: return regnum2spr (122);
+    case sim_ppc_spr123_regnum: return regnum2spr (123);
+    case sim_ppc_spr124_regnum: return regnum2spr (124);
+    case sim_ppc_spr125_regnum: return regnum2spr (125);
+    case sim_ppc_spr126_regnum: return regnum2spr (126);
+    case sim_ppc_spr127_regnum: return regnum2spr (127);
+    case sim_ppc_spr128_regnum: return regnum2spr (128);
+    case sim_ppc_spr129_regnum: return regnum2spr (129);
+    case sim_ppc_spr130_regnum: return regnum2spr (130);
+    case sim_ppc_spr131_regnum: return regnum2spr (131);
+    case sim_ppc_spr132_regnum: return regnum2spr (132);
+    case sim_ppc_spr133_regnum: return regnum2spr (133);
+    case sim_ppc_spr134_regnum: return regnum2spr (134);
+    case sim_ppc_spr135_regnum: return regnum2spr (135);
+    case sim_ppc_spr136_regnum: return regnum2spr (136);
+    case sim_ppc_spr137_regnum: return regnum2spr (137);
+    case sim_ppc_spr138_regnum: return regnum2spr (138);
+    case sim_ppc_spr139_regnum: return regnum2spr (139);
+    case sim_ppc_spr140_regnum: return regnum2spr (140);
+    case sim_ppc_spr141_regnum: return regnum2spr (141);
+    case sim_ppc_spr142_regnum: return regnum2spr (142);
+    case sim_ppc_spr143_regnum: return regnum2spr (143);
+    case sim_ppc_spr144_regnum: return regnum2spr (144);
+    case sim_ppc_spr145_regnum: return regnum2spr (145);
+    case sim_ppc_spr146_regnum: return regnum2spr (146);
+    case sim_ppc_spr147_regnum: return regnum2spr (147);
+    case sim_ppc_spr148_regnum: return regnum2spr (148);
+    case sim_ppc_spr149_regnum: return regnum2spr (149);
+    case sim_ppc_spr150_regnum: return regnum2spr (150);
+    case sim_ppc_spr151_regnum: return regnum2spr (151);
+    case sim_ppc_spr152_regnum: return regnum2spr (152);
+    case sim_ppc_spr153_regnum: return regnum2spr (153);
+    case sim_ppc_spr154_regnum: return regnum2spr (154);
+    case sim_ppc_spr155_regnum: return regnum2spr (155);
+    case sim_ppc_spr156_regnum: return regnum2spr (156);
+    case sim_ppc_spr157_regnum: return regnum2spr (157);
+    case sim_ppc_spr158_regnum: return regnum2spr (158);
+    case sim_ppc_spr159_regnum: return regnum2spr (159);
+    case sim_ppc_spr160_regnum: return regnum2spr (160);
+    case sim_ppc_spr161_regnum: return regnum2spr (161);
+    case sim_ppc_spr162_regnum: return regnum2spr (162);
+    case sim_ppc_spr163_regnum: return regnum2spr (163);
+    case sim_ppc_spr164_regnum: return regnum2spr (164);
+    case sim_ppc_spr165_regnum: return regnum2spr (165);
+    case sim_ppc_spr166_regnum: return regnum2spr (166);
+    case sim_ppc_spr167_regnum: return regnum2spr (167);
+    case sim_ppc_spr168_regnum: return regnum2spr (168);
+    case sim_ppc_spr169_regnum: return regnum2spr (169);
+    case sim_ppc_spr170_regnum: return regnum2spr (170);
+    case sim_ppc_spr171_regnum: return regnum2spr (171);
+    case sim_ppc_spr172_regnum: return regnum2spr (172);
+    case sim_ppc_spr173_regnum: return regnum2spr (173);
+    case sim_ppc_spr174_regnum: return regnum2spr (174);
+    case sim_ppc_spr175_regnum: return regnum2spr (175);
+    case sim_ppc_spr176_regnum: return regnum2spr (176);
+    case sim_ppc_spr177_regnum: return regnum2spr (177);
+    case sim_ppc_spr178_regnum: return regnum2spr (178);
+    case sim_ppc_spr179_regnum: return regnum2spr (179);
+    case sim_ppc_spr180_regnum: return regnum2spr (180);
+    case sim_ppc_spr181_regnum: return regnum2spr (181);
+    case sim_ppc_spr182_regnum: return regnum2spr (182);
+    case sim_ppc_spr183_regnum: return regnum2spr (183);
+    case sim_ppc_spr184_regnum: return regnum2spr (184);
+    case sim_ppc_spr185_regnum: return regnum2spr (185);
+    case sim_ppc_spr186_regnum: return regnum2spr (186);
+    case sim_ppc_spr187_regnum: return regnum2spr (187);
+    case sim_ppc_spr188_regnum: return regnum2spr (188);
+    case sim_ppc_spr189_regnum: return regnum2spr (189);
+    case sim_ppc_spr190_regnum: return regnum2spr (190);
+    case sim_ppc_spr191_regnum: return regnum2spr (191);
+    case sim_ppc_spr192_regnum: return regnum2spr (192);
+    case sim_ppc_spr193_regnum: return regnum2spr (193);
+    case sim_ppc_spr194_regnum: return regnum2spr (194);
+    case sim_ppc_spr195_regnum: return regnum2spr (195);
+    case sim_ppc_spr196_regnum: return regnum2spr (196);
+    case sim_ppc_spr197_regnum: return regnum2spr (197);
+    case sim_ppc_spr198_regnum: return regnum2spr (198);
+    case sim_ppc_spr199_regnum: return regnum2spr (199);
+    case sim_ppc_spr200_regnum: return regnum2spr (200);
+    case sim_ppc_spr201_regnum: return regnum2spr (201);
+    case sim_ppc_spr202_regnum: return regnum2spr (202);
+    case sim_ppc_spr203_regnum: return regnum2spr (203);
+    case sim_ppc_spr204_regnum: return regnum2spr (204);
+    case sim_ppc_spr205_regnum: return regnum2spr (205);
+    case sim_ppc_spr206_regnum: return regnum2spr (206);
+    case sim_ppc_spr207_regnum: return regnum2spr (207);
+    case sim_ppc_spr208_regnum: return regnum2spr (208);
+    case sim_ppc_spr209_regnum: return regnum2spr (209);
+    case sim_ppc_spr210_regnum: return regnum2spr (210);
+    case sim_ppc_spr211_regnum: return regnum2spr (211);
+    case sim_ppc_spr212_regnum: return regnum2spr (212);
+    case sim_ppc_spr213_regnum: return regnum2spr (213);
+    case sim_ppc_spr214_regnum: return regnum2spr (214);
+    case sim_ppc_spr215_regnum: return regnum2spr (215);
+    case sim_ppc_spr216_regnum: return regnum2spr (216);
+    case sim_ppc_spr217_regnum: return regnum2spr (217);
+    case sim_ppc_spr218_regnum: return regnum2spr (218);
+    case sim_ppc_spr219_regnum: return regnum2spr (219);
+    case sim_ppc_spr220_regnum: return regnum2spr (220);
+    case sim_ppc_spr221_regnum: return regnum2spr (221);
+    case sim_ppc_spr222_regnum: return regnum2spr (222);
+    case sim_ppc_spr223_regnum: return regnum2spr (223);
+    case sim_ppc_spr224_regnum: return regnum2spr (224);
+    case sim_ppc_spr225_regnum: return regnum2spr (225);
+    case sim_ppc_spr226_regnum: return regnum2spr (226);
+    case sim_ppc_spr227_regnum: return regnum2spr (227);
+    case sim_ppc_spr228_regnum: return regnum2spr (228);
+    case sim_ppc_spr229_regnum: return regnum2spr (229);
+    case sim_ppc_spr230_regnum: return regnum2spr (230);
+    case sim_ppc_spr231_regnum: return regnum2spr (231);
+    case sim_ppc_spr232_regnum: return regnum2spr (232);
+    case sim_ppc_spr233_regnum: return regnum2spr (233);
+    case sim_ppc_spr234_regnum: return regnum2spr (234);
+    case sim_ppc_spr235_regnum: return regnum2spr (235);
+    case sim_ppc_spr236_regnum: return regnum2spr (236);
+    case sim_ppc_spr237_regnum: return regnum2spr (237);
+    case sim_ppc_spr238_regnum: return regnum2spr (238);
+    case sim_ppc_spr239_regnum: return regnum2spr (239);
+    case sim_ppc_spr240_regnum: return regnum2spr (240);
+    case sim_ppc_spr241_regnum: return regnum2spr (241);
+    case sim_ppc_spr242_regnum: return regnum2spr (242);
+    case sim_ppc_spr243_regnum: return regnum2spr (243);
+    case sim_ppc_spr244_regnum: return regnum2spr (244);
+    case sim_ppc_spr245_regnum: return regnum2spr (245);
+    case sim_ppc_spr246_regnum: return regnum2spr (246);
+    case sim_ppc_spr247_regnum: return regnum2spr (247);
+    case sim_ppc_spr248_regnum: return regnum2spr (248);
+    case sim_ppc_spr249_regnum: return regnum2spr (249);
+    case sim_ppc_spr250_regnum: return regnum2spr (250);
+    case sim_ppc_spr251_regnum: return regnum2spr (251);
+    case sim_ppc_spr252_regnum: return regnum2spr (252);
+    case sim_ppc_spr253_regnum: return regnum2spr (253);
+    case sim_ppc_spr254_regnum: return regnum2spr (254);
+    case sim_ppc_spr255_regnum: return regnum2spr (255);
+    case sim_ppc_spr256_regnum: return regnum2spr (256);
+    case sim_ppc_spr257_regnum: return regnum2spr (257);
+    case sim_ppc_spr258_regnum: return regnum2spr (258);
+    case sim_ppc_spr259_regnum: return regnum2spr (259);
+    case sim_ppc_spr260_regnum: return regnum2spr (260);
+    case sim_ppc_spr261_regnum: return regnum2spr (261);
+    case sim_ppc_spr262_regnum: return regnum2spr (262);
+    case sim_ppc_spr263_regnum: return regnum2spr (263);
+    case sim_ppc_spr264_regnum: return regnum2spr (264);
+    case sim_ppc_spr265_regnum: return regnum2spr (265);
+    case sim_ppc_spr266_regnum: return regnum2spr (266);
+    case sim_ppc_spr267_regnum: return regnum2spr (267);
+    case sim_ppc_spr268_regnum: return regnum2spr (268);
+    case sim_ppc_spr269_regnum: return regnum2spr (269);
+    case sim_ppc_spr270_regnum: return regnum2spr (270);
+    case sim_ppc_spr271_regnum: return regnum2spr (271);
+    case sim_ppc_spr272_regnum: return regnum2spr (272);
+    case sim_ppc_spr273_regnum: return regnum2spr (273);
+    case sim_ppc_spr274_regnum: return regnum2spr (274);
+    case sim_ppc_spr275_regnum: return regnum2spr (275);
+    case sim_ppc_spr276_regnum: return regnum2spr (276);
+    case sim_ppc_spr277_regnum: return regnum2spr (277);
+    case sim_ppc_spr278_regnum: return regnum2spr (278);
+    case sim_ppc_spr279_regnum: return regnum2spr (279);
+    case sim_ppc_spr280_regnum: return regnum2spr (280);
+    case sim_ppc_spr281_regnum: return regnum2spr (281);
+    case sim_ppc_spr282_regnum: return regnum2spr (282);
+    case sim_ppc_spr283_regnum: return regnum2spr (283);
+    case sim_ppc_spr284_regnum: return regnum2spr (284);
+    case sim_ppc_spr285_regnum: return regnum2spr (285);
+    case sim_ppc_spr286_regnum: return regnum2spr (286);
+    case sim_ppc_spr287_regnum: return regnum2spr (287);
+    case sim_ppc_spr288_regnum: return regnum2spr (288);
+    case sim_ppc_spr289_regnum: return regnum2spr (289);
+    case sim_ppc_spr290_regnum: return regnum2spr (290);
+    case sim_ppc_spr291_regnum: return regnum2spr (291);
+    case sim_ppc_spr292_regnum: return regnum2spr (292);
+    case sim_ppc_spr293_regnum: return regnum2spr (293);
+    case sim_ppc_spr294_regnum: return regnum2spr (294);
+    case sim_ppc_spr295_regnum: return regnum2spr (295);
+    case sim_ppc_spr296_regnum: return regnum2spr (296);
+    case sim_ppc_spr297_regnum: return regnum2spr (297);
+    case sim_ppc_spr298_regnum: return regnum2spr (298);
+    case sim_ppc_spr299_regnum: return regnum2spr (299);
+    case sim_ppc_spr300_regnum: return regnum2spr (300);
+    case sim_ppc_spr301_regnum: return regnum2spr (301);
+    case sim_ppc_spr302_regnum: return regnum2spr (302);
+    case sim_ppc_spr303_regnum: return regnum2spr (303);
+    case sim_ppc_spr304_regnum: return regnum2spr (304);
+    case sim_ppc_spr305_regnum: return regnum2spr (305);
+    case sim_ppc_spr306_regnum: return regnum2spr (306);
+    case sim_ppc_spr307_regnum: return regnum2spr (307);
+    case sim_ppc_spr308_regnum: return regnum2spr (308);
+    case sim_ppc_spr309_regnum: return regnum2spr (309);
+    case sim_ppc_spr310_regnum: return regnum2spr (310);
+    case sim_ppc_spr311_regnum: return regnum2spr (311);
+    case sim_ppc_spr312_regnum: return regnum2spr (312);
+    case sim_ppc_spr313_regnum: return regnum2spr (313);
+    case sim_ppc_spr314_regnum: return regnum2spr (314);
+    case sim_ppc_spr315_regnum: return regnum2spr (315);
+    case sim_ppc_spr316_regnum: return regnum2spr (316);
+    case sim_ppc_spr317_regnum: return regnum2spr (317);
+    case sim_ppc_spr318_regnum: return regnum2spr (318);
+    case sim_ppc_spr319_regnum: return regnum2spr (319);
+    case sim_ppc_spr320_regnum: return regnum2spr (320);
+    case sim_ppc_spr321_regnum: return regnum2spr (321);
+    case sim_ppc_spr322_regnum: return regnum2spr (322);
+    case sim_ppc_spr323_regnum: return regnum2spr (323);
+    case sim_ppc_spr324_regnum: return regnum2spr (324);
+    case sim_ppc_spr325_regnum: return regnum2spr (325);
+    case sim_ppc_spr326_regnum: return regnum2spr (326);
+    case sim_ppc_spr327_regnum: return regnum2spr (327);
+    case sim_ppc_spr328_regnum: return regnum2spr (328);
+    case sim_ppc_spr329_regnum: return regnum2spr (329);
+    case sim_ppc_spr330_regnum: return regnum2spr (330);
+    case sim_ppc_spr331_regnum: return regnum2spr (331);
+    case sim_ppc_spr332_regnum: return regnum2spr (332);
+    case sim_ppc_spr333_regnum: return regnum2spr (333);
+    case sim_ppc_spr334_regnum: return regnum2spr (334);
+    case sim_ppc_spr335_regnum: return regnum2spr (335);
+    case sim_ppc_spr336_regnum: return regnum2spr (336);
+    case sim_ppc_spr337_regnum: return regnum2spr (337);
+    case sim_ppc_spr338_regnum: return regnum2spr (338);
+    case sim_ppc_spr339_regnum: return regnum2spr (339);
+    case sim_ppc_spr340_regnum: return regnum2spr (340);
+    case sim_ppc_spr341_regnum: return regnum2spr (341);
+    case sim_ppc_spr342_regnum: return regnum2spr (342);
+    case sim_ppc_spr343_regnum: return regnum2spr (343);
+    case sim_ppc_spr344_regnum: return regnum2spr (344);
+    case sim_ppc_spr345_regnum: return regnum2spr (345);
+    case sim_ppc_spr346_regnum: return regnum2spr (346);
+    case sim_ppc_spr347_regnum: return regnum2spr (347);
+    case sim_ppc_spr348_regnum: return regnum2spr (348);
+    case sim_ppc_spr349_regnum: return regnum2spr (349);
+    case sim_ppc_spr350_regnum: return regnum2spr (350);
+    case sim_ppc_spr351_regnum: return regnum2spr (351);
+    case sim_ppc_spr352_regnum: return regnum2spr (352);
+    case sim_ppc_spr353_regnum: return regnum2spr (353);
+    case sim_ppc_spr354_regnum: return regnum2spr (354);
+    case sim_ppc_spr355_regnum: return regnum2spr (355);
+    case sim_ppc_spr356_regnum: return regnum2spr (356);
+    case sim_ppc_spr357_regnum: return regnum2spr (357);
+    case sim_ppc_spr358_regnum: return regnum2spr (358);
+    case sim_ppc_spr359_regnum: return regnum2spr (359);
+    case sim_ppc_spr360_regnum: return regnum2spr (360);
+    case sim_ppc_spr361_regnum: return regnum2spr (361);
+    case sim_ppc_spr362_regnum: return regnum2spr (362);
+    case sim_ppc_spr363_regnum: return regnum2spr (363);
+    case sim_ppc_spr364_regnum: return regnum2spr (364);
+    case sim_ppc_spr365_regnum: return regnum2spr (365);
+    case sim_ppc_spr366_regnum: return regnum2spr (366);
+    case sim_ppc_spr367_regnum: return regnum2spr (367);
+    case sim_ppc_spr368_regnum: return regnum2spr (368);
+    case sim_ppc_spr369_regnum: return regnum2spr (369);
+    case sim_ppc_spr370_regnum: return regnum2spr (370);
+    case sim_ppc_spr371_regnum: return regnum2spr (371);
+    case sim_ppc_spr372_regnum: return regnum2spr (372);
+    case sim_ppc_spr373_regnum: return regnum2spr (373);
+    case sim_ppc_spr374_regnum: return regnum2spr (374);
+    case sim_ppc_spr375_regnum: return regnum2spr (375);
+    case sim_ppc_spr376_regnum: return regnum2spr (376);
+    case sim_ppc_spr377_regnum: return regnum2spr (377);
+    case sim_ppc_spr378_regnum: return regnum2spr (378);
+    case sim_ppc_spr379_regnum: return regnum2spr (379);
+    case sim_ppc_spr380_regnum: return regnum2spr (380);
+    case sim_ppc_spr381_regnum: return regnum2spr (381);
+    case sim_ppc_spr382_regnum: return regnum2spr (382);
+    case sim_ppc_spr383_regnum: return regnum2spr (383);
+    case sim_ppc_spr384_regnum: return regnum2spr (384);
+    case sim_ppc_spr385_regnum: return regnum2spr (385);
+    case sim_ppc_spr386_regnum: return regnum2spr (386);
+    case sim_ppc_spr387_regnum: return regnum2spr (387);
+    case sim_ppc_spr388_regnum: return regnum2spr (388);
+    case sim_ppc_spr389_regnum: return regnum2spr (389);
+    case sim_ppc_spr390_regnum: return regnum2spr (390);
+    case sim_ppc_spr391_regnum: return regnum2spr (391);
+    case sim_ppc_spr392_regnum: return regnum2spr (392);
+    case sim_ppc_spr393_regnum: return regnum2spr (393);
+    case sim_ppc_spr394_regnum: return regnum2spr (394);
+    case sim_ppc_spr395_regnum: return regnum2spr (395);
+    case sim_ppc_spr396_regnum: return regnum2spr (396);
+    case sim_ppc_spr397_regnum: return regnum2spr (397);
+    case sim_ppc_spr398_regnum: return regnum2spr (398);
+    case sim_ppc_spr399_regnum: return regnum2spr (399);
+    case sim_ppc_spr400_regnum: return regnum2spr (400);
+    case sim_ppc_spr401_regnum: return regnum2spr (401);
+    case sim_ppc_spr402_regnum: return regnum2spr (402);
+    case sim_ppc_spr403_regnum: return regnum2spr (403);
+    case sim_ppc_spr404_regnum: return regnum2spr (404);
+    case sim_ppc_spr405_regnum: return regnum2spr (405);
+    case sim_ppc_spr406_regnum: return regnum2spr (406);
+    case sim_ppc_spr407_regnum: return regnum2spr (407);
+    case sim_ppc_spr408_regnum: return regnum2spr (408);
+    case sim_ppc_spr409_regnum: return regnum2spr (409);
+    case sim_ppc_spr410_regnum: return regnum2spr (410);
+    case sim_ppc_spr411_regnum: return regnum2spr (411);
+    case sim_ppc_spr412_regnum: return regnum2spr (412);
+    case sim_ppc_spr413_regnum: return regnum2spr (413);
+    case sim_ppc_spr414_regnum: return regnum2spr (414);
+    case sim_ppc_spr415_regnum: return regnum2spr (415);
+    case sim_ppc_spr416_regnum: return regnum2spr (416);
+    case sim_ppc_spr417_regnum: return regnum2spr (417);
+    case sim_ppc_spr418_regnum: return regnum2spr (418);
+    case sim_ppc_spr419_regnum: return regnum2spr (419);
+    case sim_ppc_spr420_regnum: return regnum2spr (420);
+    case sim_ppc_spr421_regnum: return regnum2spr (421);
+    case sim_ppc_spr422_regnum: return regnum2spr (422);
+    case sim_ppc_spr423_regnum: return regnum2spr (423);
+    case sim_ppc_spr424_regnum: return regnum2spr (424);
+    case sim_ppc_spr425_regnum: return regnum2spr (425);
+    case sim_ppc_spr426_regnum: return regnum2spr (426);
+    case sim_ppc_spr427_regnum: return regnum2spr (427);
+    case sim_ppc_spr428_regnum: return regnum2spr (428);
+    case sim_ppc_spr429_regnum: return regnum2spr (429);
+    case sim_ppc_spr430_regnum: return regnum2spr (430);
+    case sim_ppc_spr431_regnum: return regnum2spr (431);
+    case sim_ppc_spr432_regnum: return regnum2spr (432);
+    case sim_ppc_spr433_regnum: return regnum2spr (433);
+    case sim_ppc_spr434_regnum: return regnum2spr (434);
+    case sim_ppc_spr435_regnum: return regnum2spr (435);
+    case sim_ppc_spr436_regnum: return regnum2spr (436);
+    case sim_ppc_spr437_regnum: return regnum2spr (437);
+    case sim_ppc_spr438_regnum: return regnum2spr (438);
+    case sim_ppc_spr439_regnum: return regnum2spr (439);
+    case sim_ppc_spr440_regnum: return regnum2spr (440);
+    case sim_ppc_spr441_regnum: return regnum2spr (441);
+    case sim_ppc_spr442_regnum: return regnum2spr (442);
+    case sim_ppc_spr443_regnum: return regnum2spr (443);
+    case sim_ppc_spr444_regnum: return regnum2spr (444);
+    case sim_ppc_spr445_regnum: return regnum2spr (445);
+    case sim_ppc_spr446_regnum: return regnum2spr (446);
+    case sim_ppc_spr447_regnum: return regnum2spr (447);
+    case sim_ppc_spr448_regnum: return regnum2spr (448);
+    case sim_ppc_spr449_regnum: return regnum2spr (449);
+    case sim_ppc_spr450_regnum: return regnum2spr (450);
+    case sim_ppc_spr451_regnum: return regnum2spr (451);
+    case sim_ppc_spr452_regnum: return regnum2spr (452);
+    case sim_ppc_spr453_regnum: return regnum2spr (453);
+    case sim_ppc_spr454_regnum: return regnum2spr (454);
+    case sim_ppc_spr455_regnum: return regnum2spr (455);
+    case sim_ppc_spr456_regnum: return regnum2spr (456);
+    case sim_ppc_spr457_regnum: return regnum2spr (457);
+    case sim_ppc_spr458_regnum: return regnum2spr (458);
+    case sim_ppc_spr459_regnum: return regnum2spr (459);
+    case sim_ppc_spr460_regnum: return regnum2spr (460);
+    case sim_ppc_spr461_regnum: return regnum2spr (461);
+    case sim_ppc_spr462_regnum: return regnum2spr (462);
+    case sim_ppc_spr463_regnum: return regnum2spr (463);
+    case sim_ppc_spr464_regnum: return regnum2spr (464);
+    case sim_ppc_spr465_regnum: return regnum2spr (465);
+    case sim_ppc_spr466_regnum: return regnum2spr (466);
+    case sim_ppc_spr467_regnum: return regnum2spr (467);
+    case sim_ppc_spr468_regnum: return regnum2spr (468);
+    case sim_ppc_spr469_regnum: return regnum2spr (469);
+    case sim_ppc_spr470_regnum: return regnum2spr (470);
+    case sim_ppc_spr471_regnum: return regnum2spr (471);
+    case sim_ppc_spr472_regnum: return regnum2spr (472);
+    case sim_ppc_spr473_regnum: return regnum2spr (473);
+    case sim_ppc_spr474_regnum: return regnum2spr (474);
+    case sim_ppc_spr475_regnum: return regnum2spr (475);
+    case sim_ppc_spr476_regnum: return regnum2spr (476);
+    case sim_ppc_spr477_regnum: return regnum2spr (477);
+    case sim_ppc_spr478_regnum: return regnum2spr (478);
+    case sim_ppc_spr479_regnum: return regnum2spr (479);
+    case sim_ppc_spr480_regnum: return regnum2spr (480);
+    case sim_ppc_spr481_regnum: return regnum2spr (481);
+    case sim_ppc_spr482_regnum: return regnum2spr (482);
+    case sim_ppc_spr483_regnum: return regnum2spr (483);
+    case sim_ppc_spr484_regnum: return regnum2spr (484);
+    case sim_ppc_spr485_regnum: return regnum2spr (485);
+    case sim_ppc_spr486_regnum: return regnum2spr (486);
+    case sim_ppc_spr487_regnum: return regnum2spr (487);
+    case sim_ppc_spr488_regnum: return regnum2spr (488);
+    case sim_ppc_spr489_regnum: return regnum2spr (489);
+    case sim_ppc_spr490_regnum: return regnum2spr (490);
+    case sim_ppc_spr491_regnum: return regnum2spr (491);
+    case sim_ppc_spr492_regnum: return regnum2spr (492);
+    case sim_ppc_spr493_regnum: return regnum2spr (493);
+    case sim_ppc_spr494_regnum: return regnum2spr (494);
+    case sim_ppc_spr495_regnum: return regnum2spr (495);
+    case sim_ppc_spr496_regnum: return regnum2spr (496);
+    case sim_ppc_spr497_regnum: return regnum2spr (497);
+    case sim_ppc_spr498_regnum: return regnum2spr (498);
+    case sim_ppc_spr499_regnum: return regnum2spr (499);
+    case sim_ppc_spr500_regnum: return regnum2spr (500);
+    case sim_ppc_spr501_regnum: return regnum2spr (501);
+    case sim_ppc_spr502_regnum: return regnum2spr (502);
+    case sim_ppc_spr503_regnum: return regnum2spr (503);
+    case sim_ppc_spr504_regnum: return regnum2spr (504);
+    case sim_ppc_spr505_regnum: return regnum2spr (505);
+    case sim_ppc_spr506_regnum: return regnum2spr (506);
+    case sim_ppc_spr507_regnum: return regnum2spr (507);
+    case sim_ppc_spr508_regnum: return regnum2spr (508);
+    case sim_ppc_spr509_regnum: return regnum2spr (509);
+    case sim_ppc_spr510_regnum: return regnum2spr (510);
+    case sim_ppc_spr511_regnum: return regnum2spr (511);
+    case sim_ppc_spr512_regnum: return regnum2spr (512);
+    case sim_ppc_spr513_regnum: return regnum2spr (513);
+    case sim_ppc_spr514_regnum: return regnum2spr (514);
+    case sim_ppc_spr515_regnum: return regnum2spr (515);
+    case sim_ppc_spr516_regnum: return regnum2spr (516);
+    case sim_ppc_spr517_regnum: return regnum2spr (517);
+    case sim_ppc_spr518_regnum: return regnum2spr (518);
+    case sim_ppc_spr519_regnum: return regnum2spr (519);
+    case sim_ppc_spr520_regnum: return regnum2spr (520);
+    case sim_ppc_spr521_regnum: return regnum2spr (521);
+    case sim_ppc_spr522_regnum: return regnum2spr (522);
+    case sim_ppc_spr523_regnum: return regnum2spr (523);
+    case sim_ppc_spr524_regnum: return regnum2spr (524);
+    case sim_ppc_spr525_regnum: return regnum2spr (525);
+    case sim_ppc_spr526_regnum: return regnum2spr (526);
+    case sim_ppc_spr527_regnum: return regnum2spr (527);
+    case sim_ppc_spr528_regnum: return regnum2spr (528);
+    case sim_ppc_spr529_regnum: return regnum2spr (529);
+    case sim_ppc_spr530_regnum: return regnum2spr (530);
+    case sim_ppc_spr531_regnum: return regnum2spr (531);
+    case sim_ppc_spr532_regnum: return regnum2spr (532);
+    case sim_ppc_spr533_regnum: return regnum2spr (533);
+    case sim_ppc_spr534_regnum: return regnum2spr (534);
+    case sim_ppc_spr535_regnum: return regnum2spr (535);
+    case sim_ppc_spr536_regnum: return regnum2spr (536);
+    case sim_ppc_spr537_regnum: return regnum2spr (537);
+    case sim_ppc_spr538_regnum: return regnum2spr (538);
+    case sim_ppc_spr539_regnum: return regnum2spr (539);
+    case sim_ppc_spr540_regnum: return regnum2spr (540);
+    case sim_ppc_spr541_regnum: return regnum2spr (541);
+    case sim_ppc_spr542_regnum: return regnum2spr (542);
+    case sim_ppc_spr543_regnum: return regnum2spr (543);
+    case sim_ppc_spr544_regnum: return regnum2spr (544);
+    case sim_ppc_spr545_regnum: return regnum2spr (545);
+    case sim_ppc_spr546_regnum: return regnum2spr (546);
+    case sim_ppc_spr547_regnum: return regnum2spr (547);
+    case sim_ppc_spr548_regnum: return regnum2spr (548);
+    case sim_ppc_spr549_regnum: return regnum2spr (549);
+    case sim_ppc_spr550_regnum: return regnum2spr (550);
+    case sim_ppc_spr551_regnum: return regnum2spr (551);
+    case sim_ppc_spr552_regnum: return regnum2spr (552);
+    case sim_ppc_spr553_regnum: return regnum2spr (553);
+    case sim_ppc_spr554_regnum: return regnum2spr (554);
+    case sim_ppc_spr555_regnum: return regnum2spr (555);
+    case sim_ppc_spr556_regnum: return regnum2spr (556);
+    case sim_ppc_spr557_regnum: return regnum2spr (557);
+    case sim_ppc_spr558_regnum: return regnum2spr (558);
+    case sim_ppc_spr559_regnum: return regnum2spr (559);
+    case sim_ppc_spr560_regnum: return regnum2spr (560);
+    case sim_ppc_spr561_regnum: return regnum2spr (561);
+    case sim_ppc_spr562_regnum: return regnum2spr (562);
+    case sim_ppc_spr563_regnum: return regnum2spr (563);
+    case sim_ppc_spr564_regnum: return regnum2spr (564);
+    case sim_ppc_spr565_regnum: return regnum2spr (565);
+    case sim_ppc_spr566_regnum: return regnum2spr (566);
+    case sim_ppc_spr567_regnum: return regnum2spr (567);
+    case sim_ppc_spr568_regnum: return regnum2spr (568);
+    case sim_ppc_spr569_regnum: return regnum2spr (569);
+    case sim_ppc_spr570_regnum: return regnum2spr (570);
+    case sim_ppc_spr571_regnum: return regnum2spr (571);
+    case sim_ppc_spr572_regnum: return regnum2spr (572);
+    case sim_ppc_spr573_regnum: return regnum2spr (573);
+    case sim_ppc_spr574_regnum: return regnum2spr (574);
+    case sim_ppc_spr575_regnum: return regnum2spr (575);
+    case sim_ppc_spr576_regnum: return regnum2spr (576);
+    case sim_ppc_spr577_regnum: return regnum2spr (577);
+    case sim_ppc_spr578_regnum: return regnum2spr (578);
+    case sim_ppc_spr579_regnum: return regnum2spr (579);
+    case sim_ppc_spr580_regnum: return regnum2spr (580);
+    case sim_ppc_spr581_regnum: return regnum2spr (581);
+    case sim_ppc_spr582_regnum: return regnum2spr (582);
+    case sim_ppc_spr583_regnum: return regnum2spr (583);
+    case sim_ppc_spr584_regnum: return regnum2spr (584);
+    case sim_ppc_spr585_regnum: return regnum2spr (585);
+    case sim_ppc_spr586_regnum: return regnum2spr (586);
+    case sim_ppc_spr587_regnum: return regnum2spr (587);
+    case sim_ppc_spr588_regnum: return regnum2spr (588);
+    case sim_ppc_spr589_regnum: return regnum2spr (589);
+    case sim_ppc_spr590_regnum: return regnum2spr (590);
+    case sim_ppc_spr591_regnum: return regnum2spr (591);
+    case sim_ppc_spr592_regnum: return regnum2spr (592);
+    case sim_ppc_spr593_regnum: return regnum2spr (593);
+    case sim_ppc_spr594_regnum: return regnum2spr (594);
+    case sim_ppc_spr595_regnum: return regnum2spr (595);
+    case sim_ppc_spr596_regnum: return regnum2spr (596);
+    case sim_ppc_spr597_regnum: return regnum2spr (597);
+    case sim_ppc_spr598_regnum: return regnum2spr (598);
+    case sim_ppc_spr599_regnum: return regnum2spr (599);
+    case sim_ppc_spr600_regnum: return regnum2spr (600);
+    case sim_ppc_spr601_regnum: return regnum2spr (601);
+    case sim_ppc_spr602_regnum: return regnum2spr (602);
+    case sim_ppc_spr603_regnum: return regnum2spr (603);
+    case sim_ppc_spr604_regnum: return regnum2spr (604);
+    case sim_ppc_spr605_regnum: return regnum2spr (605);
+    case sim_ppc_spr606_regnum: return regnum2spr (606);
+    case sim_ppc_spr607_regnum: return regnum2spr (607);
+    case sim_ppc_spr608_regnum: return regnum2spr (608);
+    case sim_ppc_spr609_regnum: return regnum2spr (609);
+    case sim_ppc_spr610_regnum: return regnum2spr (610);
+    case sim_ppc_spr611_regnum: return regnum2spr (611);
+    case sim_ppc_spr612_regnum: return regnum2spr (612);
+    case sim_ppc_spr613_regnum: return regnum2spr (613);
+    case sim_ppc_spr614_regnum: return regnum2spr (614);
+    case sim_ppc_spr615_regnum: return regnum2spr (615);
+    case sim_ppc_spr616_regnum: return regnum2spr (616);
+    case sim_ppc_spr617_regnum: return regnum2spr (617);
+    case sim_ppc_spr618_regnum: return regnum2spr (618);
+    case sim_ppc_spr619_regnum: return regnum2spr (619);
+    case sim_ppc_spr620_regnum: return regnum2spr (620);
+    case sim_ppc_spr621_regnum: return regnum2spr (621);
+    case sim_ppc_spr622_regnum: return regnum2spr (622);
+    case sim_ppc_spr623_regnum: return regnum2spr (623);
+    case sim_ppc_spr624_regnum: return regnum2spr (624);
+    case sim_ppc_spr625_regnum: return regnum2spr (625);
+    case sim_ppc_spr626_regnum: return regnum2spr (626);
+    case sim_ppc_spr627_regnum: return regnum2spr (627);
+    case sim_ppc_spr628_regnum: return regnum2spr (628);
+    case sim_ppc_spr629_regnum: return regnum2spr (629);
+    case sim_ppc_spr630_regnum: return regnum2spr (630);
+    case sim_ppc_spr631_regnum: return regnum2spr (631);
+    case sim_ppc_spr632_regnum: return regnum2spr (632);
+    case sim_ppc_spr633_regnum: return regnum2spr (633);
+    case sim_ppc_spr634_regnum: return regnum2spr (634);
+    case sim_ppc_spr635_regnum: return regnum2spr (635);
+    case sim_ppc_spr636_regnum: return regnum2spr (636);
+    case sim_ppc_spr637_regnum: return regnum2spr (637);
+    case sim_ppc_spr638_regnum: return regnum2spr (638);
+    case sim_ppc_spr639_regnum: return regnum2spr (639);
+    case sim_ppc_spr640_regnum: return regnum2spr (640);
+    case sim_ppc_spr641_regnum: return regnum2spr (641);
+    case sim_ppc_spr642_regnum: return regnum2spr (642);
+    case sim_ppc_spr643_regnum: return regnum2spr (643);
+    case sim_ppc_spr644_regnum: return regnum2spr (644);
+    case sim_ppc_spr645_regnum: return regnum2spr (645);
+    case sim_ppc_spr646_regnum: return regnum2spr (646);
+    case sim_ppc_spr647_regnum: return regnum2spr (647);
+    case sim_ppc_spr648_regnum: return regnum2spr (648);
+    case sim_ppc_spr649_regnum: return regnum2spr (649);
+    case sim_ppc_spr650_regnum: return regnum2spr (650);
+    case sim_ppc_spr651_regnum: return regnum2spr (651);
+    case sim_ppc_spr652_regnum: return regnum2spr (652);
+    case sim_ppc_spr653_regnum: return regnum2spr (653);
+    case sim_ppc_spr654_regnum: return regnum2spr (654);
+    case sim_ppc_spr655_regnum: return regnum2spr (655);
+    case sim_ppc_spr656_regnum: return regnum2spr (656);
+    case sim_ppc_spr657_regnum: return regnum2spr (657);
+    case sim_ppc_spr658_regnum: return regnum2spr (658);
+    case sim_ppc_spr659_regnum: return regnum2spr (659);
+    case sim_ppc_spr660_regnum: return regnum2spr (660);
+    case sim_ppc_spr661_regnum: return regnum2spr (661);
+    case sim_ppc_spr662_regnum: return regnum2spr (662);
+    case sim_ppc_spr663_regnum: return regnum2spr (663);
+    case sim_ppc_spr664_regnum: return regnum2spr (664);
+    case sim_ppc_spr665_regnum: return regnum2spr (665);
+    case sim_ppc_spr666_regnum: return regnum2spr (666);
+    case sim_ppc_spr667_regnum: return regnum2spr (667);
+    case sim_ppc_spr668_regnum: return regnum2spr (668);
+    case sim_ppc_spr669_regnum: return regnum2spr (669);
+    case sim_ppc_spr670_regnum: return regnum2spr (670);
+    case sim_ppc_spr671_regnum: return regnum2spr (671);
+    case sim_ppc_spr672_regnum: return regnum2spr (672);
+    case sim_ppc_spr673_regnum: return regnum2spr (673);
+    case sim_ppc_spr674_regnum: return regnum2spr (674);
+    case sim_ppc_spr675_regnum: return regnum2spr (675);
+    case sim_ppc_spr676_regnum: return regnum2spr (676);
+    case sim_ppc_spr677_regnum: return regnum2spr (677);
+    case sim_ppc_spr678_regnum: return regnum2spr (678);
+    case sim_ppc_spr679_regnum: return regnum2spr (679);
+    case sim_ppc_spr680_regnum: return regnum2spr (680);
+    case sim_ppc_spr681_regnum: return regnum2spr (681);
+    case sim_ppc_spr682_regnum: return regnum2spr (682);
+    case sim_ppc_spr683_regnum: return regnum2spr (683);
+    case sim_ppc_spr684_regnum: return regnum2spr (684);
+    case sim_ppc_spr685_regnum: return regnum2spr (685);
+    case sim_ppc_spr686_regnum: return regnum2spr (686);
+    case sim_ppc_spr687_regnum: return regnum2spr (687);
+    case sim_ppc_spr688_regnum: return regnum2spr (688);
+    case sim_ppc_spr689_regnum: return regnum2spr (689);
+    case sim_ppc_spr690_regnum: return regnum2spr (690);
+    case sim_ppc_spr691_regnum: return regnum2spr (691);
+    case sim_ppc_spr692_regnum: return regnum2spr (692);
+    case sim_ppc_spr693_regnum: return regnum2spr (693);
+    case sim_ppc_spr694_regnum: return regnum2spr (694);
+    case sim_ppc_spr695_regnum: return regnum2spr (695);
+    case sim_ppc_spr696_regnum: return regnum2spr (696);
+    case sim_ppc_spr697_regnum: return regnum2spr (697);
+    case sim_ppc_spr698_regnum: return regnum2spr (698);
+    case sim_ppc_spr699_regnum: return regnum2spr (699);
+    case sim_ppc_spr700_regnum: return regnum2spr (700);
+    case sim_ppc_spr701_regnum: return regnum2spr (701);
+    case sim_ppc_spr702_regnum: return regnum2spr (702);
+    case sim_ppc_spr703_regnum: return regnum2spr (703);
+    case sim_ppc_spr704_regnum: return regnum2spr (704);
+    case sim_ppc_spr705_regnum: return regnum2spr (705);
+    case sim_ppc_spr706_regnum: return regnum2spr (706);
+    case sim_ppc_spr707_regnum: return regnum2spr (707);
+    case sim_ppc_spr708_regnum: return regnum2spr (708);
+    case sim_ppc_spr709_regnum: return regnum2spr (709);
+    case sim_ppc_spr710_regnum: return regnum2spr (710);
+    case sim_ppc_spr711_regnum: return regnum2spr (711);
+    case sim_ppc_spr712_regnum: return regnum2spr (712);
+    case sim_ppc_spr713_regnum: return regnum2spr (713);
+    case sim_ppc_spr714_regnum: return regnum2spr (714);
+    case sim_ppc_spr715_regnum: return regnum2spr (715);
+    case sim_ppc_spr716_regnum: return regnum2spr (716);
+    case sim_ppc_spr717_regnum: return regnum2spr (717);
+    case sim_ppc_spr718_regnum: return regnum2spr (718);
+    case sim_ppc_spr719_regnum: return regnum2spr (719);
+    case sim_ppc_spr720_regnum: return regnum2spr (720);
+    case sim_ppc_spr721_regnum: return regnum2spr (721);
+    case sim_ppc_spr722_regnum: return regnum2spr (722);
+    case sim_ppc_spr723_regnum: return regnum2spr (723);
+    case sim_ppc_spr724_regnum: return regnum2spr (724);
+    case sim_ppc_spr725_regnum: return regnum2spr (725);
+    case sim_ppc_spr726_regnum: return regnum2spr (726);
+    case sim_ppc_spr727_regnum: return regnum2spr (727);
+    case sim_ppc_spr728_regnum: return regnum2spr (728);
+    case sim_ppc_spr729_regnum: return regnum2spr (729);
+    case sim_ppc_spr730_regnum: return regnum2spr (730);
+    case sim_ppc_spr731_regnum: return regnum2spr (731);
+    case sim_ppc_spr732_regnum: return regnum2spr (732);
+    case sim_ppc_spr733_regnum: return regnum2spr (733);
+    case sim_ppc_spr734_regnum: return regnum2spr (734);
+    case sim_ppc_spr735_regnum: return regnum2spr (735);
+    case sim_ppc_spr736_regnum: return regnum2spr (736);
+    case sim_ppc_spr737_regnum: return regnum2spr (737);
+    case sim_ppc_spr738_regnum: return regnum2spr (738);
+    case sim_ppc_spr739_regnum: return regnum2spr (739);
+    case sim_ppc_spr740_regnum: return regnum2spr (740);
+    case sim_ppc_spr741_regnum: return regnum2spr (741);
+    case sim_ppc_spr742_regnum: return regnum2spr (742);
+    case sim_ppc_spr743_regnum: return regnum2spr (743);
+    case sim_ppc_spr744_regnum: return regnum2spr (744);
+    case sim_ppc_spr745_regnum: return regnum2spr (745);
+    case sim_ppc_spr746_regnum: return regnum2spr (746);
+    case sim_ppc_spr747_regnum: return regnum2spr (747);
+    case sim_ppc_spr748_regnum: return regnum2spr (748);
+    case sim_ppc_spr749_regnum: return regnum2spr (749);
+    case sim_ppc_spr750_regnum: return regnum2spr (750);
+    case sim_ppc_spr751_regnum: return regnum2spr (751);
+    case sim_ppc_spr752_regnum: return regnum2spr (752);
+    case sim_ppc_spr753_regnum: return regnum2spr (753);
+    case sim_ppc_spr754_regnum: return regnum2spr (754);
+    case sim_ppc_spr755_regnum: return regnum2spr (755);
+    case sim_ppc_spr756_regnum: return regnum2spr (756);
+    case sim_ppc_spr757_regnum: return regnum2spr (757);
+    case sim_ppc_spr758_regnum: return regnum2spr (758);
+    case sim_ppc_spr759_regnum: return regnum2spr (759);
+    case sim_ppc_spr760_regnum: return regnum2spr (760);
+    case sim_ppc_spr761_regnum: return regnum2spr (761);
+    case sim_ppc_spr762_regnum: return regnum2spr (762);
+    case sim_ppc_spr763_regnum: return regnum2spr (763);
+    case sim_ppc_spr764_regnum: return regnum2spr (764);
+    case sim_ppc_spr765_regnum: return regnum2spr (765);
+    case sim_ppc_spr766_regnum: return regnum2spr (766);
+    case sim_ppc_spr767_regnum: return regnum2spr (767);
+    case sim_ppc_spr768_regnum: return regnum2spr (768);
+    case sim_ppc_spr769_regnum: return regnum2spr (769);
+    case sim_ppc_spr770_regnum: return regnum2spr (770);
+    case sim_ppc_spr771_regnum: return regnum2spr (771);
+    case sim_ppc_spr772_regnum: return regnum2spr (772);
+    case sim_ppc_spr773_regnum: return regnum2spr (773);
+    case sim_ppc_spr774_regnum: return regnum2spr (774);
+    case sim_ppc_spr775_regnum: return regnum2spr (775);
+    case sim_ppc_spr776_regnum: return regnum2spr (776);
+    case sim_ppc_spr777_regnum: return regnum2spr (777);
+    case sim_ppc_spr778_regnum: return regnum2spr (778);
+    case sim_ppc_spr779_regnum: return regnum2spr (779);
+    case sim_ppc_spr780_regnum: return regnum2spr (780);
+    case sim_ppc_spr781_regnum: return regnum2spr (781);
+    case sim_ppc_spr782_regnum: return regnum2spr (782);
+    case sim_ppc_spr783_regnum: return regnum2spr (783);
+    case sim_ppc_spr784_regnum: return regnum2spr (784);
+    case sim_ppc_spr785_regnum: return regnum2spr (785);
+    case sim_ppc_spr786_regnum: return regnum2spr (786);
+    case sim_ppc_spr787_regnum: return regnum2spr (787);
+    case sim_ppc_spr788_regnum: return regnum2spr (788);
+    case sim_ppc_spr789_regnum: return regnum2spr (789);
+    case sim_ppc_spr790_regnum: return regnum2spr (790);
+    case sim_ppc_spr791_regnum: return regnum2spr (791);
+    case sim_ppc_spr792_regnum: return regnum2spr (792);
+    case sim_ppc_spr793_regnum: return regnum2spr (793);
+    case sim_ppc_spr794_regnum: return regnum2spr (794);
+    case sim_ppc_spr795_regnum: return regnum2spr (795);
+    case sim_ppc_spr796_regnum: return regnum2spr (796);
+    case sim_ppc_spr797_regnum: return regnum2spr (797);
+    case sim_ppc_spr798_regnum: return regnum2spr (798);
+    case sim_ppc_spr799_regnum: return regnum2spr (799);
+    case sim_ppc_spr800_regnum: return regnum2spr (800);
+    case sim_ppc_spr801_regnum: return regnum2spr (801);
+    case sim_ppc_spr802_regnum: return regnum2spr (802);
+    case sim_ppc_spr803_regnum: return regnum2spr (803);
+    case sim_ppc_spr804_regnum: return regnum2spr (804);
+    case sim_ppc_spr805_regnum: return regnum2spr (805);
+    case sim_ppc_spr806_regnum: return regnum2spr (806);
+    case sim_ppc_spr807_regnum: return regnum2spr (807);
+    case sim_ppc_spr808_regnum: return regnum2spr (808);
+    case sim_ppc_spr809_regnum: return regnum2spr (809);
+    case sim_ppc_spr810_regnum: return regnum2spr (810);
+    case sim_ppc_spr811_regnum: return regnum2spr (811);
+    case sim_ppc_spr812_regnum: return regnum2spr (812);
+    case sim_ppc_spr813_regnum: return regnum2spr (813);
+    case sim_ppc_spr814_regnum: return regnum2spr (814);
+    case sim_ppc_spr815_regnum: return regnum2spr (815);
+    case sim_ppc_spr816_regnum: return regnum2spr (816);
+    case sim_ppc_spr817_regnum: return regnum2spr (817);
+    case sim_ppc_spr818_regnum: return regnum2spr (818);
+    case sim_ppc_spr819_regnum: return regnum2spr (819);
+    case sim_ppc_spr820_regnum: return regnum2spr (820);
+    case sim_ppc_spr821_regnum: return regnum2spr (821);
+    case sim_ppc_spr822_regnum: return regnum2spr (822);
+    case sim_ppc_spr823_regnum: return regnum2spr (823);
+    case sim_ppc_spr824_regnum: return regnum2spr (824);
+    case sim_ppc_spr825_regnum: return regnum2spr (825);
+    case sim_ppc_spr826_regnum: return regnum2spr (826);
+    case sim_ppc_spr827_regnum: return regnum2spr (827);
+    case sim_ppc_spr828_regnum: return regnum2spr (828);
+    case sim_ppc_spr829_regnum: return regnum2spr (829);
+    case sim_ppc_spr830_regnum: return regnum2spr (830);
+    case sim_ppc_spr831_regnum: return regnum2spr (831);
+    case sim_ppc_spr832_regnum: return regnum2spr (832);
+    case sim_ppc_spr833_regnum: return regnum2spr (833);
+    case sim_ppc_spr834_regnum: return regnum2spr (834);
+    case sim_ppc_spr835_regnum: return regnum2spr (835);
+    case sim_ppc_spr836_regnum: return regnum2spr (836);
+    case sim_ppc_spr837_regnum: return regnum2spr (837);
+    case sim_ppc_spr838_regnum: return regnum2spr (838);
+    case sim_ppc_spr839_regnum: return regnum2spr (839);
+    case sim_ppc_spr840_regnum: return regnum2spr (840);
+    case sim_ppc_spr841_regnum: return regnum2spr (841);
+    case sim_ppc_spr842_regnum: return regnum2spr (842);
+    case sim_ppc_spr843_regnum: return regnum2spr (843);
+    case sim_ppc_spr844_regnum: return regnum2spr (844);
+    case sim_ppc_spr845_regnum: return regnum2spr (845);
+    case sim_ppc_spr846_regnum: return regnum2spr (846);
+    case sim_ppc_spr847_regnum: return regnum2spr (847);
+    case sim_ppc_spr848_regnum: return regnum2spr (848);
+    case sim_ppc_spr849_regnum: return regnum2spr (849);
+    case sim_ppc_spr850_regnum: return regnum2spr (850);
+    case sim_ppc_spr851_regnum: return regnum2spr (851);
+    case sim_ppc_spr852_regnum: return regnum2spr (852);
+    case sim_ppc_spr853_regnum: return regnum2spr (853);
+    case sim_ppc_spr854_regnum: return regnum2spr (854);
+    case sim_ppc_spr855_regnum: return regnum2spr (855);
+    case sim_ppc_spr856_regnum: return regnum2spr (856);
+    case sim_ppc_spr857_regnum: return regnum2spr (857);
+    case sim_ppc_spr858_regnum: return regnum2spr (858);
+    case sim_ppc_spr859_regnum: return regnum2spr (859);
+    case sim_ppc_spr860_regnum: return regnum2spr (860);
+    case sim_ppc_spr861_regnum: return regnum2spr (861);
+    case sim_ppc_spr862_regnum: return regnum2spr (862);
+    case sim_ppc_spr863_regnum: return regnum2spr (863);
+    case sim_ppc_spr864_regnum: return regnum2spr (864);
+    case sim_ppc_spr865_regnum: return regnum2spr (865);
+    case sim_ppc_spr866_regnum: return regnum2spr (866);
+    case sim_ppc_spr867_regnum: return regnum2spr (867);
+    case sim_ppc_spr868_regnum: return regnum2spr (868);
+    case sim_ppc_spr869_regnum: return regnum2spr (869);
+    case sim_ppc_spr870_regnum: return regnum2spr (870);
+    case sim_ppc_spr871_regnum: return regnum2spr (871);
+    case sim_ppc_spr872_regnum: return regnum2spr (872);
+    case sim_ppc_spr873_regnum: return regnum2spr (873);
+    case sim_ppc_spr874_regnum: return regnum2spr (874);
+    case sim_ppc_spr875_regnum: return regnum2spr (875);
+    case sim_ppc_spr876_regnum: return regnum2spr (876);
+    case sim_ppc_spr877_regnum: return regnum2spr (877);
+    case sim_ppc_spr878_regnum: return regnum2spr (878);
+    case sim_ppc_spr879_regnum: return regnum2spr (879);
+    case sim_ppc_spr880_regnum: return regnum2spr (880);
+    case sim_ppc_spr881_regnum: return regnum2spr (881);
+    case sim_ppc_spr882_regnum: return regnum2spr (882);
+    case sim_ppc_spr883_regnum: return regnum2spr (883);
+    case sim_ppc_spr884_regnum: return regnum2spr (884);
+    case sim_ppc_spr885_regnum: return regnum2spr (885);
+    case sim_ppc_spr886_regnum: return regnum2spr (886);
+    case sim_ppc_spr887_regnum: return regnum2spr (887);
+    case sim_ppc_spr888_regnum: return regnum2spr (888);
+    case sim_ppc_spr889_regnum: return regnum2spr (889);
+    case sim_ppc_spr890_regnum: return regnum2spr (890);
+    case sim_ppc_spr891_regnum: return regnum2spr (891);
+    case sim_ppc_spr892_regnum: return regnum2spr (892);
+    case sim_ppc_spr893_regnum: return regnum2spr (893);
+    case sim_ppc_spr894_regnum: return regnum2spr (894);
+    case sim_ppc_spr895_regnum: return regnum2spr (895);
+    case sim_ppc_spr896_regnum: return regnum2spr (896);
+    case sim_ppc_spr897_regnum: return regnum2spr (897);
+    case sim_ppc_spr898_regnum: return regnum2spr (898);
+    case sim_ppc_spr899_regnum: return regnum2spr (899);
+    case sim_ppc_spr900_regnum: return regnum2spr (900);
+    case sim_ppc_spr901_regnum: return regnum2spr (901);
+    case sim_ppc_spr902_regnum: return regnum2spr (902);
+    case sim_ppc_spr903_regnum: return regnum2spr (903);
+    case sim_ppc_spr904_regnum: return regnum2spr (904);
+    case sim_ppc_spr905_regnum: return regnum2spr (905);
+    case sim_ppc_spr906_regnum: return regnum2spr (906);
+    case sim_ppc_spr907_regnum: return regnum2spr (907);
+    case sim_ppc_spr908_regnum: return regnum2spr (908);
+    case sim_ppc_spr909_regnum: return regnum2spr (909);
+    case sim_ppc_spr910_regnum: return regnum2spr (910);
+    case sim_ppc_spr911_regnum: return regnum2spr (911);
+    case sim_ppc_spr912_regnum: return regnum2spr (912);
+    case sim_ppc_spr913_regnum: return regnum2spr (913);
+    case sim_ppc_spr914_regnum: return regnum2spr (914);
+    case sim_ppc_spr915_regnum: return regnum2spr (915);
+    case sim_ppc_spr916_regnum: return regnum2spr (916);
+    case sim_ppc_spr917_regnum: return regnum2spr (917);
+    case sim_ppc_spr918_regnum: return regnum2spr (918);
+    case sim_ppc_spr919_regnum: return regnum2spr (919);
+    case sim_ppc_spr920_regnum: return regnum2spr (920);
+    case sim_ppc_spr921_regnum: return regnum2spr (921);
+    case sim_ppc_spr922_regnum: return regnum2spr (922);
+    case sim_ppc_spr923_regnum: return regnum2spr (923);
+    case sim_ppc_spr924_regnum: return regnum2spr (924);
+    case sim_ppc_spr925_regnum: return regnum2spr (925);
+    case sim_ppc_spr926_regnum: return regnum2spr (926);
+    case sim_ppc_spr927_regnum: return regnum2spr (927);
+    case sim_ppc_spr928_regnum: return regnum2spr (928);
+    case sim_ppc_spr929_regnum: return regnum2spr (929);
+    case sim_ppc_spr930_regnum: return regnum2spr (930);
+    case sim_ppc_spr931_regnum: return regnum2spr (931);
+    case sim_ppc_spr932_regnum: return regnum2spr (932);
+    case sim_ppc_spr933_regnum: return regnum2spr (933);
+    case sim_ppc_spr934_regnum: return regnum2spr (934);
+    case sim_ppc_spr935_regnum: return regnum2spr (935);
+    case sim_ppc_spr936_regnum: return regnum2spr (936);
+    case sim_ppc_spr937_regnum: return regnum2spr (937);
+    case sim_ppc_spr938_regnum: return regnum2spr (938);
+    case sim_ppc_spr939_regnum: return regnum2spr (939);
+    case sim_ppc_spr940_regnum: return regnum2spr (940);
+    case sim_ppc_spr941_regnum: return regnum2spr (941);
+    case sim_ppc_spr942_regnum: return regnum2spr (942);
+    case sim_ppc_spr943_regnum: return regnum2spr (943);
+    case sim_ppc_spr944_regnum: return regnum2spr (944);
+    case sim_ppc_spr945_regnum: return regnum2spr (945);
+    case sim_ppc_spr946_regnum: return regnum2spr (946);
+    case sim_ppc_spr947_regnum: return regnum2spr (947);
+    case sim_ppc_spr948_regnum: return regnum2spr (948);
+    case sim_ppc_spr949_regnum: return regnum2spr (949);
+    case sim_ppc_spr950_regnum: return regnum2spr (950);
+    case sim_ppc_spr951_regnum: return regnum2spr (951);
+    case sim_ppc_spr952_regnum: return regnum2spr (952);
+    case sim_ppc_spr953_regnum: return regnum2spr (953);
+    case sim_ppc_spr954_regnum: return regnum2spr (954);
+    case sim_ppc_spr955_regnum: return regnum2spr (955);
+    case sim_ppc_spr956_regnum: return regnum2spr (956);
+    case sim_ppc_spr957_regnum: return regnum2spr (957);
+    case sim_ppc_spr958_regnum: return regnum2spr (958);
+    case sim_ppc_spr959_regnum: return regnum2spr (959);
+    case sim_ppc_spr960_regnum: return regnum2spr (960);
+    case sim_ppc_spr961_regnum: return regnum2spr (961);
+    case sim_ppc_spr962_regnum: return regnum2spr (962);
+    case sim_ppc_spr963_regnum: return regnum2spr (963);
+    case sim_ppc_spr964_regnum: return regnum2spr (964);
+    case sim_ppc_spr965_regnum: return regnum2spr (965);
+    case sim_ppc_spr966_regnum: return regnum2spr (966);
+    case sim_ppc_spr967_regnum: return regnum2spr (967);
+    case sim_ppc_spr968_regnum: return regnum2spr (968);
+    case sim_ppc_spr969_regnum: return regnum2spr (969);
+    case sim_ppc_spr970_regnum: return regnum2spr (970);
+    case sim_ppc_spr971_regnum: return regnum2spr (971);
+    case sim_ppc_spr972_regnum: return regnum2spr (972);
+    case sim_ppc_spr973_regnum: return regnum2spr (973);
+    case sim_ppc_spr974_regnum: return regnum2spr (974);
+    case sim_ppc_spr975_regnum: return regnum2spr (975);
+    case sim_ppc_spr976_regnum: return regnum2spr (976);
+    case sim_ppc_spr977_regnum: return regnum2spr (977);
+    case sim_ppc_spr978_regnum: return regnum2spr (978);
+    case sim_ppc_spr979_regnum: return regnum2spr (979);
+    case sim_ppc_spr980_regnum: return regnum2spr (980);
+    case sim_ppc_spr981_regnum: return regnum2spr (981);
+    case sim_ppc_spr982_regnum: return regnum2spr (982);
+    case sim_ppc_spr983_regnum: return regnum2spr (983);
+    case sim_ppc_spr984_regnum: return regnum2spr (984);
+    case sim_ppc_spr985_regnum: return regnum2spr (985);
+    case sim_ppc_spr986_regnum: return regnum2spr (986);
+    case sim_ppc_spr987_regnum: return regnum2spr (987);
+    case sim_ppc_spr988_regnum: return regnum2spr (988);
+    case sim_ppc_spr989_regnum: return regnum2spr (989);
+    case sim_ppc_spr990_regnum: return regnum2spr (990);
+    case sim_ppc_spr991_regnum: return regnum2spr (991);
+    case sim_ppc_spr992_regnum: return regnum2spr (992);
+    case sim_ppc_spr993_regnum: return regnum2spr (993);
+    case sim_ppc_spr994_regnum: return regnum2spr (994);
+    case sim_ppc_spr995_regnum: return regnum2spr (995);
+    case sim_ppc_spr996_regnum: return regnum2spr (996);
+    case sim_ppc_spr997_regnum: return regnum2spr (997);
+    case sim_ppc_spr998_regnum: return regnum2spr (998);
+    case sim_ppc_spr999_regnum: return regnum2spr (999);
+    case sim_ppc_spr1000_regnum: return regnum2spr (1000);
+    case sim_ppc_spr1001_regnum: return regnum2spr (1001);
+    case sim_ppc_spr1002_regnum: return regnum2spr (1002);
+    case sim_ppc_spr1003_regnum: return regnum2spr (1003);
+    case sim_ppc_spr1004_regnum: return regnum2spr (1004);
+    case sim_ppc_spr1005_regnum: return regnum2spr (1005);
+    case sim_ppc_spr1006_regnum: return regnum2spr (1006);
+    case sim_ppc_spr1007_regnum: return regnum2spr (1007);
+    case sim_ppc_spr1008_regnum: return regnum2spr (1008);
+    case sim_ppc_spr1009_regnum: return regnum2spr (1009);
+    case sim_ppc_spr1010_regnum: return regnum2spr (1010);
+    case sim_ppc_spr1011_regnum: return regnum2spr (1011);
+    case sim_ppc_spr1012_regnum: return regnum2spr (1012);
+    case sim_ppc_spr1013_regnum: return regnum2spr (1013);
+    case sim_ppc_spr1014_regnum: return regnum2spr (1014);
+    case sim_ppc_spr1015_regnum: return regnum2spr (1015);
+    case sim_ppc_spr1016_regnum: return regnum2spr (1016);
+    case sim_ppc_spr1017_regnum: return regnum2spr (1017);
+    case sim_ppc_spr1018_regnum: return regnum2spr (1018);
+    case sim_ppc_spr1019_regnum: return regnum2spr (1019);
+    case sim_ppc_spr1020_regnum: return regnum2spr (1020);
+    case sim_ppc_spr1021_regnum: return regnum2spr (1021);
+    case sim_ppc_spr1022_regnum: return regnum2spr (1022);
+    case sim_ppc_spr1023_regnum: return regnum2spr (1023);
+    default:
+      /* Not a valid register number at all.  */
+      return NULL;
+    }
+}
+
+
+int
+sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
+{
+  const char *regname = regnum2name (regno);
+
+  if (simulator == NULL || regname == NULL)
+    return -1;
+
+  TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n",
+                   regno, regname, (long)buf));
+  return psim_read_register(simulator, MAX_NR_PROCESSORS,
+                           buf, regname, raw_transfer);
+}
+
+
+int
+sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
+{
+  const char *regname = regnum2name (regno);
+
+  if (simulator == NULL || regname == NULL)
+    return -1;
+
+  TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n",
+                   regno, regname, (long)buf));
+  return psim_write_register(simulator, MAX_NR_PROCESSORS,
+                            buf, regname, raw_transfer);
+}
diff --git a/sim/testsuite/sim/mips/fpu64-ps-sb1.s b/sim/testsuite/sim/mips/fpu64-ps-sb1.s
new file mode 100644 (file)
index 0000000..a39d079
--- /dev/null
@@ -0,0 +1,72 @@
+# mips test sanity, expected to pass.
+# mach:         sb1
+# as:          -mabi=eabi
+# ld:          -N -Ttext=0x80010000
+# output:      *\\npass\\n
+
+       .include "testutils.inc"
+
+        .macro check_ps psval, upperval, lowerval
+       .set push
+       .set noreorder
+       cvt.s.pu        $f0, \psval             # upper
+       cvt.s.pl        $f2, \psval             # lower
+       li.s            $f4, \upperval
+       li.s            $f6, \lowerval
+       c.eq.s          $fcc0, $f0, $f4
+       bc1f            $fcc0, _fail
+        c.eq.s         $fcc0, $f2, $f6
+       bc1f            $fcc0, _fail
+        nop
+       .set pop
+        .endm
+
+       setup
+
+       .set noreorder
+
+       .ent DIAG
+DIAG:
+
+       # make sure that Status.FR, .CU1, and .SBX are set.
+       mfc0    $2, $12
+       or      $2, $2, (1 << 26) | (1 << 29) | (1 << 16)
+       mtc0    $2, $12
+
+
+       li.s    $f10, 4.0
+       li.s    $f12, 16.0
+       cvt.ps.s $f20, $f10, $f12               # $f20: u=4.0, l=16.0
+
+       li.s    $f10, -1.0
+       li.s    $f12, 2.0
+       cvt.ps.s $f22, $f10, $f12               # $f22: u=-1.0, l=2.0
+
+
+       writemsg "div.ps"
+
+       div.ps $f8, $f20, $f22
+       check_ps $f8, -4.0, 8.0
+
+
+       writemsg "recip.ps"
+
+       recip.ps $f8, $f20
+       check_ps $f8, 0.25, 0.0625
+
+
+       writemsg "rsqrt.ps"
+
+       rsqrt.ps $f8, $f20
+       check_ps $f8, 0.5, 0.25
+
+
+       writemsg "sqrt.ps"
+
+       sqrt.ps $f8, $f20
+       check_ps $f8, 2.0, 4.0
+
+
+       pass
+
+       .end DIAG
diff --git a/sim/testsuite/sim/mips/fpu64-ps.s b/sim/testsuite/sim/mips/fpu64-ps.s
new file mode 100644 (file)
index 0000000..ad493b8
--- /dev/null
@@ -0,0 +1,367 @@
+# mips test sanity, expected to pass.
+# mach:         mips64 sb1
+# as:          -mabi=eabi
+# ld:          -N -Ttext=0x80010000
+# output:      *\\npass\\n
+
+       .include "testutils.inc"
+
+        .macro check_ps psval, upperval, lowerval
+       .set push
+       .set noreorder
+       cvt.s.pu        $f0, \psval             # upper
+       cvt.s.pl        $f2, \psval             # lower
+       li.s            $f4, \upperval
+       li.s            $f6, \lowerval
+       c.eq.s          $fcc0, $f0, $f4
+       bc1f            $fcc0, _fail
+        c.eq.s         $fcc0, $f2, $f6
+       bc1f            $fcc0, _fail
+        nop
+       .set pop
+        .endm
+
+       setup
+
+       .set noreorder
+
+       .ent DIAG
+DIAG:
+
+       # make sure that Status.FR and .CU1 are set.
+       mfc0    $2, $12
+       or      $2, $2, (1 << 26) | (1 << 29)
+       mtc0    $2, $12
+
+
+       writemsg "ldc1"
+
+       .data
+1:     .dword  0xc1a8000042200000              # -21.0, 40.0
+       .text
+       la      $2, 1b
+       ldc1    $f8, 0($2)
+       check_ps $f8, -21.0, 40.0
+
+
+       writemsg "cvt.ps.s"
+
+       li.s    $f10, 1.0
+       li.s    $f12, 3.0
+       cvt.ps.s $f8, $f10, $f12                # upper, lower
+       check_ps $f8, 1.0, 3.0
+
+
+       writemsg "cvt.ps.s, sdc1, copy, ldc1"
+
+       .data
+1:     .dword  0
+       .dword  0
+       .text
+       la      $2, 1b
+       li.s    $f12, -4.0
+       li.s    $f14, 32.0
+       cvt.ps.s $f10, $f12, $f14               # upper, lower
+       sdc1    $f10, 8($2)
+       lw      $3, 8($2)
+       lw      $4, 12($2)
+       sw      $3, 0($2)
+       sw      $4, 4($2)
+       ldc1    $f8, 0($2)
+       check_ps $f8, -4.0, 32.0
+
+
+       # Load some constants for later use
+
+       li.s    $f10, 4.0
+       li.s    $f12, 16.0
+       cvt.ps.s $f20, $f10, $f12               # $f20: u=4.0, l=16.0
+
+       li.s    $f10, -1.0
+       li.s    $f12, 2.0
+       cvt.ps.s $f22, $f10, $f12               # $f22: u=-1.0, l=2.0
+
+       li.s    $f10, 17.0
+       li.s    $f12, -8.0
+       cvt.ps.s $f24, $f10, $f12               # $f24: u=17.0, l=-8.0
+
+
+       writemsg "pll.ps"
+
+       pll.ps  $f8, $f20, $f22
+       check_ps $f8, 16.0, 2.0
+
+
+       writemsg "plu.ps"
+
+       plu.ps  $f8, $f20, $f22
+       check_ps $f8, 16.0, -1.0
+
+
+       writemsg "pul.ps"
+
+       pul.ps  $f8, $f20, $f22
+       check_ps $f8, 4.0, 2.0
+
+
+       writemsg "puu.ps"
+
+       puu.ps  $f8, $f20, $f22
+       check_ps $f8, 4.0, -1.0
+
+
+       writemsg "abs.ps"
+
+       abs.ps  $f8, $f22
+       check_ps $f8, 1.0, 2.0
+
+
+       writemsg "mov.ps"
+
+       mov.ps  $f8, $f22
+       check_ps $f8, -1.0, 2.0
+
+
+       writemsg "neg.ps"
+
+       neg.ps  $f8, $f22
+       check_ps $f8, 1.0, -2.0
+
+
+       writemsg "add.ps"
+
+       add.ps  $f8, $f20, $f22
+       check_ps $f8, 3.0, 18.0
+
+
+       writemsg "mul.ps"
+
+       mul.ps  $f8, $f20, $f22
+       check_ps $f8, -4.0, 32.0
+
+
+       writemsg "sub.ps"
+
+       sub.ps  $f8, $f20, $f22
+       check_ps $f8, 5.0, 14.0
+
+
+       writemsg "madd.ps"
+
+       madd.ps $f8, $f24, $f20, $f22
+       check_ps $f8, 13.0, 24.0
+
+
+       writemsg "msub.ps"
+
+       msub.ps $f8, $f24, $f20, $f22
+       check_ps $f8, -21.0, 40.0
+
+
+       writemsg "nmadd.ps"
+
+       nmadd.ps $f8, $f24, $f20, $f22
+       check_ps $f8, -13.0, -24.0
+
+
+       writemsg "nmsub.ps"
+
+       nmsub.ps $f8, $f24, $f20, $f22
+       check_ps $f8, 21.0, -40.0
+
+
+       writemsg "movn.ps (n)"
+
+       li      $2, 0
+       mov.ps  $f8, $f20
+       movn.ps $f8, $f22, $2           # doesn't move
+       check_ps $f8, 4.0, 16.0
+
+
+       writemsg "movn.ps (y)"
+
+       li      $2, 1
+       mov.ps  $f8, $f20
+       movn.ps $f8, $f22, $2           # does move
+       check_ps $f8, -1.0, 2.0
+
+
+       writemsg "movz.ps (y)"
+
+       li      $2, 0
+       mov.ps  $f8, $f20
+       movz.ps $f8, $f22, $2           # does move
+       check_ps $f8, -1.0, 2.0
+
+
+       writemsg "movz.ps (n)"
+
+       li      $2, 1
+       mov.ps  $f8, $f20
+       movz.ps $f8, $f22, $2           # doesn't move
+       check_ps $f8, 4.0, 16.0
+
+
+       writemsg "movf.ps (y,y)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (1 << 23) | (1 << 25)
+       ctc1    $2, $31                 # clear fcc0, clear fcc1
+       mov.ps  $f8, $f20
+       movf.ps $f8, $f22, $fcc0        # moves both halves
+       check_ps $f8, -1.0, 2.0
+
+
+       writemsg "movf.ps (y,n)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (0 << 23) | (1 << 25)
+       ctc1    $2, $31                 # set fcc0, clear fcc1
+       mov.ps  $f8, $f20
+       movf.ps $f8, $f22, $fcc0        # moves upper half only
+       check_ps $f8, -1.0, 16.0
+
+
+       writemsg "movf.ps (n,y)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (1 << 23) | (0 << 25)
+       ctc1    $2, $31                 # clear fcc0, set fcc1
+       mov.ps  $f8, $f20
+       movf.ps $f8, $f22, $fcc0        # moves lower half only
+       check_ps $f8, 4.0, 2.0
+
+
+       writemsg "movf.ps (n,n)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (0 << 23) | (0 << 25)
+       ctc1    $2, $31                 # set fcc0, set fcc1
+       mov.ps  $f8, $f20
+       movf.ps $f8, $f22, $fcc0        # doesn't move either half
+       check_ps $f8, 4.0, 16.0
+
+
+       writemsg "movt.ps (n,n)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (1 << 23) | (1 << 25)
+       ctc1    $2, $31                 # clear fcc0, clear fcc1
+       mov.ps  $f8, $f20
+       movt.ps $f8, $f22, $fcc0        # doesn't move either half
+       check_ps $f8, 4.0, 16.0
+
+
+       writemsg "movt.ps (n,y)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (0 << 23) | (1 << 25)
+       ctc1    $2, $31                 # set fcc0, clear fcc1
+       mov.ps  $f8, $f20
+       movt.ps $f8, $f22, $fcc0        # moves lower half only
+       check_ps $f8, 4.0, 2.0
+
+
+       writemsg "movt.ps (y,n)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (1 << 23) | (0 << 25)
+       ctc1    $2, $31                 # clear fcc0, set fcc1
+       mov.ps  $f8, $f20
+       movt.ps $f8, $f22, $fcc0        # moves upper half only
+       check_ps $f8, -1.0, 16.0
+
+
+       writemsg "movt.ps (y,y)"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (1 << 25)
+       xor     $2, $2, (0 << 23) | (0 << 25)
+       ctc1    $2, $31                 # set fcc0, set fcc1
+       mov.ps  $f8, $f20
+       movt.ps $f8, $f22, $fcc0        # moves both halves
+       check_ps $f8, -1.0, 2.0
+
+
+       writemsg "alnv.ps (aligned)"
+
+       .data
+1:     .dword  0xc1a8000042200000              # -21.0, 40.0
+       .dword  0xc228000041a00000              # -42.0, 20.0
+       .text
+       la      $2, 1b
+       li      $3, 0
+       addu    $4, $3, 8
+       luxc1   $f10, $3($2)
+       luxc1   $f12, $4($2)
+       alnv.ps $f8, $f10, $f12, $3
+       check_ps $f8, -21.0, 40.0
+
+
+       writemsg "alnv.ps (unaligned)"
+
+       .data
+1:     .dword  0xc1a8000042200000              # -21.0, 40.0
+       .dword  0xc228000041a00000              # -42.0, 20.0
+       .hword  0x0001
+       .text
+       la      $2, 1b
+       li      $3, 4
+       addu    $4, $3, 8
+       luxc1   $f10, $3($2)
+       luxc1   $f12, $4($2)
+       alnv.ps $f8, $f10, $f12, $3
+
+       lb      $5, 16($2)
+       bnez    $5, 2f                          # little endian
+        nop
+
+       # big endian
+       check_ps $f8, 40.0, -42.0
+       b       3f
+        nop
+2:
+       # little endian
+       check_ps $f8, 20.0, -21.0
+3:
+
+
+       # We test c.cond.ps only lightly, just to make sure it modifies
+       # two bits and compares the halves separately.  Perhaps it should
+       # be tested more thoroughly.
+
+       writemsg "c.f.ps"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (0x7f << 25)
+       ctc1    $2, $31                 # set all fcc bits
+       c.f.ps  $fcc0, $f8, $f8         # -> f, f
+       bc1t    $fcc0, _fail
+        nop
+       bc1t    $fcc1, _fail
+        nop
+
+       
+       writemsg "c.olt.ps"
+
+       cfc1    $2, $31 
+       or      $2, $2, (1 << 23) | (0x7f << 25)
+       xor     $2, $2, (1 << 23) | (0x7f << 25)
+       ctc1    $2, $31                 # clear all fcc bits
+       c.lt.ps $fcc0, $f22, $f24       # -> f, t
+       bc1t    $fcc0, _fail
+        nop
+       bc1f    $fcc1, _fail
+        nop
+       
+
+       pass
+
+       .end DIAG
diff --git a/sim/testsuite/sim/mips/mdmx-ob-sb1.s b/sim/testsuite/sim/mips/mdmx-ob-sb1.s
new file mode 100644 (file)
index 0000000..c8409fc
--- /dev/null
@@ -0,0 +1,102 @@
+# MDMX .OB op tests.
+# mach:         sb1
+# as:          -mabi=eabi
+# ld:          -N -Ttext=0x80010000
+# output:      *\\npass\\n
+
+       .include "testutils.inc"
+       .include "utils-mdmx.inc"
+
+       setup
+
+       .set noreorder
+
+       .ent DIAG
+DIAG:
+
+       enable_mdmx
+
+       # set Status.SBX to enable SB-1 extensions.
+       mfc0    $2, $12
+       or      $2, $2, (1 << 16)
+       mtc0    $2, $12
+
+
+       ###
+       ### SB-1 Non-accumulator .ob format ops.
+       ###
+       ### Key: v = vector
+       ###      ev = vector of single element
+       ###      cv = vector of constant.
+       ###
+
+
+       writemsg "pavg.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       pavg.ob $f10, $f8, $f9
+       ck_ob $f10, 0x3c4d5e6f8091a2b3
+
+       writemsg "pavg.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       pavg.ob $f10, $f8, $f9[6]
+       ck_ob $f10, 0x444d555e666f7780
+
+       writemsg "pavg.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       pavg.ob $f10, $f8, 0x10
+       ck_ob $f10, 0x1119222a333b444c
+
+
+       writemsg "pabsdiff.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       pabsdiff.ob     $f10, $f8, $f9
+       ck_ob $f10, 0x5555555555555555
+
+       writemsg "pabsdiff.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       pabsdiff.ob     $f10, $f8, $f9[7]
+       ck_ob $f10, 0x5544332211001122
+
+       writemsg "pabsdiff.ob (cv)"
+       ld_ob   $f8, 0x0001020304050607
+       pabsdiff.ob     $f10, $f8, 0x04
+       ck_ob $f10, 0x0403020100010203
+
+
+       ###
+       ### SB-1 Accumulator .ob format ops
+       ###
+       ### Key: v = vector
+       ###      ev = vector of single element
+       ###      cv = vector of constant.
+       ###
+
+
+       writemsg "pabsdiffc.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       pabsdiffc.ob $f8, $f9
+       ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x5555555555555555
+
+       writemsg "pabsdiffc.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       pabsdiffc.ob $f8, $f9[7]
+       ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x5544332211001122
+
+       writemsg "pabsdiffc.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x0001020304050607
+       pabsdiffc.ob $f8, 0x04
+       ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0403020100010203
+
+
+       pass
+
+       .end DIAG
diff --git a/sim/testsuite/sim/mips/mdmx-ob.s b/sim/testsuite/sim/mips/mdmx-ob.s
new file mode 100644 (file)
index 0000000..ad9bbda
--- /dev/null
@@ -0,0 +1,631 @@
+# MDMX .OB op tests.
+# mach:         mips64 sb1
+# as:          -mabi=eabi
+# as(mips64):  -mabi=eabi -mdmx
+# ld:          -N -Ttext=0x80010000
+# output:      *\\npass\\n
+
+       .include "testutils.inc"
+       .include "utils-fpu.inc"
+       .include "utils-mdmx.inc"
+
+       setup
+
+       .set noreorder
+
+       .ent DIAG
+DIAG:
+
+       enable_mdmx
+
+
+       ###
+       ### Non-accumulator, non-CC-using .ob format ops.
+       ###
+       ### Key: v = vector
+       ###      ev = vector of single element
+       ###      cv = vector of constant.
+       ###
+
+
+       writemsg "add.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       add.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x7799bbddffffffff
+
+       writemsg "add.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       add.ob  $f10, $f8, $f9[6]
+       ck_ob   $f10, 0x8899aabbccddeeff
+
+       writemsg "add.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       add.ob  $f10, $f8, 0x10
+       ck_ob   $f10, 0x2132435465768798
+
+
+       writemsg "alni.ob"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       alni.ob $f10, $f8, $f9, 3
+       ck_ob   $f10, 0x4455667788667788
+
+
+       writemsg "alnv.ob"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       li      $4, 5
+       alnv.ob $f10, $f8, $f9, $4
+       ck_ob   $f10, 0x66778866778899aa
+
+
+       writemsg "and.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       and.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x0022000000224488
+
+       writemsg "and.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       and.ob  $f10, $f8, $f9[4]
+       ck_ob   $f10, 0x1100110011001188
+
+       writemsg "and.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       and.ob  $f10, $f8, 0x1e
+       ck_ob   $f10, 0x1002120414061608
+
+
+       writemsg "max.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       max.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x66778899aabbccdd
+
+       writemsg "max.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       max.ob  $f10, $f8, $f9[7]
+       ck_ob   $f10, 0x6666666666667788
+
+       writemsg "max.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       max.ob  $f10, $f8, 0x15
+       ck_ob   $f10, 0x1522334455667788
+
+
+       writemsg "min.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       min.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x1122334455667788
+
+       writemsg "min.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       min.ob  $f10, $f8, $f9[7]
+       ck_ob   $f10, 0x1122334455666666
+
+       writemsg "min.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       min.ob  $f10, $f8, 0x15
+       ck_ob   $f10, 0x1115151515151515
+
+
+       writemsg "mul.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x0001020304050607
+       mul.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x002266ccffffffff
+
+       writemsg "mul.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x0001020304050607
+       mul.ob  $f10, $f8, $f9[4]
+       ck_ob   $f10, 0x336699ccffffffff
+
+       writemsg "mul.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       mul.ob  $f10, $f8, 2
+       ck_ob   $f10, 0x22446688aacceeff
+
+
+       writemsg "nor.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       nor.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x8888442200000022
+
+       writemsg "nor.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       nor.ob  $f10, $f8, $f9[6]
+       ck_ob   $f10, 0x8888888888888800
+
+       writemsg "nor.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       nor.ob  $f10, $f8, 0x08
+       ck_ob   $f10, 0xe6d5c4b3a2918077
+
+
+       writemsg "or.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       or.ob   $f10, $f8, $f9
+       ck_ob   $f10, 0x7777bbddffffffdd
+
+       writemsg "or.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       or.ob   $f10, $f8, $f9[6]
+       ck_ob   $f10, 0x77777777777777ff
+
+       writemsg "or.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       or.ob   $f10, $f8, 0x08
+       ck_ob   $f10, 0x192a3b4c5d6e7f88
+
+
+       writemsg "shfl.mixh.ob"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       shfl.mixh.ob    $f10, $f8, $f9
+       ck_ob   $f10, 0x1166227733884499
+
+
+       writemsg "shfl.mixl.ob"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       shfl.mixl.ob    $f10, $f8, $f9
+       ck_ob   $f10, 0x55aa66bb77cc88dd
+
+
+       writemsg "shfl.pach.ob"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       shfl.pach.ob    $f10, $f8, $f9
+       ck_ob   $f10, 0x113355776688aacc
+
+
+       writemsg "shfl.upsl.ob"
+       ld_ob   $f8, 0x1122334455667788
+       shfl.upsl.ob    $f10, $f8, $f8
+       ck_ob   $f10, 0x005500660077ff88
+
+
+       writemsg "sll.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x0001020304050607
+       sll.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x1144cc2050c0c000
+
+       writemsg "sll.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x0001020304050607
+       sll.ob  $f10, $f8, $f9[3]
+       ck_ob   $f10, 0x1020304050607080
+
+       writemsg "sll.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       sll.ob  $f10, $f8, 1
+       ck_ob   $f10, 0x22446688aaccee10
+
+
+       writemsg "srl.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x0001020304050607
+       srl.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x11110c0805030101
+
+       writemsg "srl.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x0001020304050607
+       srl.ob  $f10, $f8, $f9[3]
+       ck_ob   $f10, 0x0102030405060708
+
+       writemsg "srl.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       srl.ob  $f10, $f8, 1
+       ck_ob   $f10, 0x081119222a333b44
+
+
+       writemsg "sub.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x0001020304050607
+       sub.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x1121314151617181
+
+       writemsg "sub.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       sub.ob  $f10, $f8, $f9[7]
+       ck_ob   $f10, 0x0000000000001122
+
+       writemsg "sub.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       sub.ob  $f10, $f8, 0x10
+       ck_ob   $f10, 0x0112233445566778
+
+
+       writemsg "xor.ob (v)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       xor.ob  $f10, $f8, $f9
+       ck_ob   $f10, 0x7755bbddffddbb55
+
+       writemsg "xor.ob (ev)"
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       xor.ob  $f10, $f8, $f9[6]
+       ck_ob   $f10, 0x66554433221100ff
+
+       writemsg "xor.ob (cv)"
+       ld_ob   $f8, 0x1122334455667788
+       xor.ob  $f10, $f8, 0x08
+       ck_ob   $f10, 0x192a3b4c5d6e7f80
+
+
+       ###
+       ### Accumulator .ob format ops (in order: rd/wr, math, scale/round)
+       ###
+       ### Key: v = vector
+       ###      ev = vector of single element
+       ###      cv = vector of constant.
+       ###
+
+
+       writemsg "wacl.ob / rac[hml].ob"
+       ld_ob   $f8, 0x8001028304850687
+       ld_ob   $f9, 0x1011121314151617
+       wacl.ob $f8, $f9
+       ck_acc_ob 0xff0000ff00ff00ff, 0x8001028304850687, 0x1011121314151617
+
+       # Note: relies on data left in accumulator by previous test.
+       writemsg "wach.ob / rac[hml].ob"
+       ld_ob   $f8, 0x2021222324252627
+       wach.ob $f8
+       ck_acc_ob 0x2021222324252627, 0x8001028304850687, 0x1011121314151617
+
+
+       writemsg "adda.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       adda.ob $f8, $f9
+       ck_acc_ob 0x0001020304050607, 0x0000000000010101, 0x7799bbddff214365
+
+       writemsg "adda.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       adda.ob $f8, $f9[2]
+       ck_acc_ob 0x0001020304050607, 0x0000000001010101, 0xccddeeff10213243
+
+       writemsg "adda.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       adda.ob $f8, 0x1f
+       ck_acc_ob 0x0001020304050607, 0x0000000000000000, 0x30415263748596a7
+
+
+       writemsg "addl.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       addl.ob $f8, $f9
+       ck_acc_ob 0x0000000000000000, 0x0000000000010101, 0x7799bbddff214365
+
+       writemsg "addl.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       addl.ob $f8, $f9[2]
+       ck_acc_ob 0x0000000000000000, 0x0000000001010101, 0xccddeeff10213243
+
+       writemsg "addl.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       addl.ob $f8, 0x1f
+       ck_acc_ob 0x0000000000000000, 0x0000000000000000, 0x30415263748596a7
+
+
+       writemsg "mula.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       mula.ob $f8, $f9
+       ck_acc_ob 0x0001020304050607, 0x060f1b28384a5e75, 0xc6ce18a47282d468
+
+       writemsg "mula.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       mula.ob $f8, $f9[2]
+       ck_acc_ob 0x0001020304050607, 0x0c1825313e4a5663, 0x6bd641ac1782ed58
+
+       writemsg "mula.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       mula.ob $f8, 0x1f
+       ck_acc_ob 0x0001020304050607, 0x020406080a0c0e10, 0x0f1e2d3c4b5a6978
+
+
+       writemsg "mull.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       mull.ob $f8, $f9
+       ck_acc_ob 0x0000000000000000, 0x060f1b28384a5e75, 0xc6ce18a47282d468
+
+       writemsg "mull.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       mull.ob $f8, $f9[2]
+       ck_acc_ob 0x0000000000000000, 0x0c1825313e4a5663, 0x6bd641ac1782ed58
+
+       writemsg "mull.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       mull.ob $f8, 0x1f
+       ck_acc_ob 0x0000000000000000, 0x020406080a0c0e10, 0x0f1e2d3c4b5a6978
+
+
+       writemsg "muls.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       muls.ob $f8, $f9
+       ck_acc_ob 0xff00010203040506, 0xf9f0e4d7c7b5a18a, 0x3a32e85c8e7e2c98
+
+       writemsg "muls.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       muls.ob $f8, $f9[2]
+       ck_acc_ob 0xff00010203040506, 0xf3e7dacec1b5a99c, 0x952abf54e97e13a8
+
+       writemsg "muls.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       muls.ob $f8, 0x1f
+       ck_acc_ob 0xff00010203040506, 0xfdfbf9f7f5f3f1ef, 0xf1e2d3c4b5a69788
+
+
+       writemsg "mulsl.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       mulsl.ob $f8, $f9
+       ck_acc_ob 0xffffffffffffffff, 0xf9f0e4d7c7b5a18a, 0x3a32e85c8e7e2c98
+
+       writemsg "mulsl.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       mulsl.ob $f8, $f9[2]
+       ck_acc_ob 0xffffffffffffffff, 0xf3e7dacec1b5a99c, 0x952abf54e97e13a8
+
+       writemsg "mulsl.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       mulsl.ob $f8, 0x1f
+       ck_acc_ob 0xffffffffffffffff, 0xfdfbf9f7f5f3f1ef, 0xf1e2d3c4b5a69788
+
+
+       writemsg "suba.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       suba.ob $f8, $f9
+       ck_acc_ob 0xff00010203040506, 0xffffffffffffffff, 0xabababababababab
+
+       writemsg "suba.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       suba.ob $f8, $f9[2]
+       ck_acc_ob 0xff00010203040506, 0xffffffffffffffff, 0x566778899aabbccd
+
+       writemsg "suba.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       suba.ob $f8, 0x1f
+       ck_acc_ob 0xff01020304050607, 0xff00000000000000, 0xf203142536475869
+
+
+       writemsg "subl.ob (v)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       subl.ob $f8, $f9
+       ck_acc_ob 0xffffffffffffffff, 0xffffffffffffffff, 0xabababababababab
+
+       writemsg "subl.ob (ev)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       ld_ob   $f9, 0x66778899aabbccdd
+       subl.ob $f8, $f9[2]
+       ck_acc_ob 0xffffffffffffffff, 0xffffffffffffffff, 0x566778899aabbccd
+
+       writemsg "subl.ob (cv)"
+       ld_acc_ob 0x0001020304050607, 0x0000000000000000, 0x0000000000000000
+       ld_ob   $f8, 0x1122334455667788
+       subl.ob $f8, 0x1f
+       ck_acc_ob 0xff00000000000000, 0xff00000000000000, 0xf203142536475869
+
+
+       writemsg "rnau.ob (v)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       ld_ob   $f8, 0x0001020304050607
+       rnau.ob $f9, $f8
+       ck_ob   $f9, 0x4021110940201008
+
+       writemsg "rnau.ob (ev)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       ld_ob   $f8, 0x0001020304050607
+       rnau.ob $f9, $f8[4]
+       ck_ob   $f9, 0x080809097f7f8080
+
+       writemsg "rnau.ob (cv)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       rnau.ob $f9, 2
+       ck_ob   $f9, 0x10111112feffffff
+
+
+       writemsg "rneu.ob (v)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       ld_ob   $f8, 0x0001020304050607
+       rneu.ob $f9, $f8
+       ck_ob   $f9, 0x4021110940201008
+
+       writemsg "rneu.ob (ev)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       ld_ob   $f8, 0x0001020304050607
+       rneu.ob $f9, $f8[4]
+       ck_ob   $f9, 0x080808097f7f8080
+
+       writemsg "rneu.ob (cv)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       rneu.ob $f9, 2
+       ck_ob   $f9, 0x10101112fefeffff
+
+
+       writemsg "rzu.ob (v)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       ld_ob   $f8, 0x0001020304050607
+       rzu.ob  $f9, $f8
+       ck_ob   $f9, 0x402111083f1f0f07
+
+       writemsg "rzu.ob (ev)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       ld_ob   $f8, 0x0001020304050607
+       rzu.ob  $f9, $f8[4]
+       ck_ob   $f9, 0x080808087f7f7f7f
+
+       writemsg "rzu.ob (cv)"
+       ld_acc_ob 0x0000000000000000, 0x0000000003030303, 0x40424446f8fafcfe
+       rzu.ob  $f9, 2
+       ck_ob   $f9, 0x10101111fefeffff
+
+
+       ###
+       ### CC-using .ob format ops.
+       ###
+       ### Key: v = vector
+       ###      ev = vector of single element
+       ###      cv = vector of constant.
+       ###
+
+
+       writemsg "c.eq.ob (v)"
+       ld_ob   $f8, 0x0001010202030304
+       ld_ob   $f9, 0x0101020203030404
+       clr_fp_cc 0xff
+       c.eq.ob $f8, $f9
+       ck_fp_cc 0x55
+
+       writemsg "c.eq.ob (ev)"
+       ld_ob   $f8, 0x0001010202030304
+       ld_ob   $f9, 0x0101020203030404
+       clr_fp_cc 0xff
+       c.eq.ob $f8, $f9[5]
+       ck_fp_cc 0x18
+
+       writemsg "c.eq.ob (cv)"
+       ld_ob   $f8, 0x0001010202030304
+       clr_fp_cc 0xff
+       c.eq.ob $f8, 0x03
+       ck_fp_cc 0x06
+
+
+       writemsg "c.le.ob (v)"
+       ld_ob   $f8, 0x0001010202030304
+       ld_ob   $f9, 0x0101020203030404
+       clr_fp_cc 0xff
+       c.le.ob $f8, $f9
+       ck_fp_cc 0xff
+
+       writemsg "c.le.ob (ev)"
+       ld_ob   $f8, 0x0001010202030304
+       ld_ob   $f9, 0x0101020203030404
+       clr_fp_cc 0xff
+       c.le.ob $f8, $f9[5]
+       ck_fp_cc 0xf8
+
+       writemsg "c.le.ob (cv)"
+       ld_ob   $f8, 0x0001010202030304
+       clr_fp_cc 0xff
+       c.le.ob $f8, 0x03
+       ck_fp_cc 0xfe
+
+
+       writemsg "c.lt.ob (v)"
+       ld_ob   $f8, 0x0001010202030304
+       ld_ob   $f9, 0x0101020203030404
+       clr_fp_cc 0xff
+       c.lt.ob $f8, $f9
+       ck_fp_cc 0xaa
+
+       writemsg "c.lt.ob (ev)"
+       ld_ob   $f8, 0x0001010202030304
+       ld_ob   $f9, 0x0101020203030404
+       clr_fp_cc 0xff
+       c.lt.ob $f8, $f9[5]
+       ck_fp_cc 0xe0
+
+       writemsg "c.lt.ob (cv)"
+       ld_ob   $f8, 0x0001010202030304
+       clr_fp_cc 0xff
+       c.lt.ob $f8, 0x03
+       ck_fp_cc 0xf8
+
+
+       writemsg "pickf.ob (v)"
+       ld_ob   $f8, 0x0001020304050607
+       ld_ob   $f9, 0x08090a0b0c0d0e0f
+       clrset_fp_cc 0xff, 0xaa
+       pickf.ob $f10, $f8, $f9
+       ck_ob   $f10, 0x08010a030c050e07
+
+       writemsg "pickf.ob (ev)"
+       ld_ob   $f8, 0x0001020304050607
+       ld_ob   $f9, 0x08090a0b0c0d0e0f
+       clrset_fp_cc 0xff, 0xaa
+       pickf.ob $f10, $f8, $f9[4]
+       ck_ob   $f10, 0x0b010b030b050b07
+
+       writemsg "pickf.ob (cv)"
+       ld_ob   $f8, 0x0001020304050607
+       clrset_fp_cc 0xff, 0xaa
+       pickf.ob $f10, $f8, 0x10
+       ck_ob   $f10, 0x1001100310051007
+
+
+       writemsg "pickt.ob (v)"
+       ld_ob   $f8, 0x0001020304050607
+       ld_ob   $f9, 0x08090a0b0c0d0e0f
+       clrset_fp_cc 0xff, 0xaa
+       pickt.ob $f10, $f8, $f9
+       ck_ob   $f10, 0x0009020b040d060f
+
+       writemsg "pickt.ob (ev)"
+       ld_ob   $f8, 0x0001020304050607
+       ld_ob   $f9, 0x08090a0b0c0d0e0f
+       clrset_fp_cc 0xff, 0xaa
+       pickt.ob $f10, $f8, $f9[5]
+       ck_ob   $f10, 0x000a020a040a060a
+
+       writemsg "pickt.ob (cv)"
+       ld_ob   $f8, 0x0001020304050607
+       clrset_fp_cc 0xff, 0xaa
+       pickt.ob $f10, $f8, 0x10
+       ck_ob   $f10, 0x0010021004100610
+
+
+       pass
+
+       .end DIAG
diff --git a/sim/testsuite/sim/mips/utils-fpu.inc b/sim/testsuite/sim/mips/utils-fpu.inc
new file mode 100644 (file)
index 0000000..82feb61
--- /dev/null
@@ -0,0 +1,105 @@
+# MIPS simulator testsuite FPU utility functions.
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Contributed by Chris Demetriou of Broadcom Corporation.
+#
+# This file is part of the GNU simulators.
+#
+# 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, 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.  */
+
+       .macro  enable_fpu fr
+        mfc0    $20, $12
+        or      $20, $20, (1 << 29) | (\fr << 26)
+        mtc0    $20, $20
+       .endm
+
+       ###
+       ### Data movement macros
+       ###
+
+       .macro ld_fp_df r, v
+       .data
+1:     .double \v
+       .previous
+       ldc1    \r, 1b
+       .endm
+
+       .macro ld_fp_di r, v
+       .data
+1:     .dword  \v
+       .previous
+       ldc1    \r, 1b
+       .endm
+
+       .macro ld_fp_sf r, v
+       .data
+1:     .float  \v
+       .previous
+       lwc1    \r, 1b
+       .endm
+
+       .macro ld_fp_si r, v
+       .data
+1:     .word   \v
+       .previous
+       lwc1    \r, 1b
+       .endm
+
+
+       ###
+       ### FP condition code manipulation macros
+       ###
+
+       .macro clrset_fp_cc clr, set
+       cfc1    $20, $31        
+       or      $20, $20, (((\clr & 0xfe) << 24) | ((\clr & 0x01) << 23))
+       xor     $20, $20, (((\clr & 0xfe) << 24) | ((\clr & 0x01) << 23))
+       or      $20, $20, (((\set & 0xfe) << 24) | ((\set & 0x01) << 23))
+       ctc1    $20, $31
+       .endm
+
+       .macro clr_fp_cc clr
+       clrset_fp_cc \clr, 0
+       .endm
+
+       .macro set_fp_cc set
+       clrset_fp_cc 0, \set
+       .endm
+
+       .macro get_fp_cc r
+       .set push
+       .set noat
+       cfc1    $1, $31
+       srl     $1, $1, 23
+       andi    \r, $1, 0x1fc
+       andi    $1, $1, 0x1
+       srl     \r, \r, 1
+       or      \r, \r, $1
+       .set pop
+       .endm
+
+       .macro ck_fp_cc v
+       get_fp_cc $20
+       xori    $20, $20, \v
+       bnez    $20, _fail
+        nop
+       .endm
+
+       .macro ckm_fp_cc v, mask
+       get_fp_cc $20
+       xori    $20, $20, \v
+       andi    $20, $20, \mask
+       bnez    $20, _fail
+        nop
+       .endm
diff --git a/sim/testsuite/sim/mips/utils-mdmx.inc b/sim/testsuite/sim/mips/utils-mdmx.inc
new file mode 100644 (file)
index 0000000..cda6550
--- /dev/null
@@ -0,0 +1,72 @@
+# MIPS simulator testsuite MDMX utility functions.
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Contributed by Chris Demetriou of Broadcom Corporation.
+#
+# This file is part of the GNU simulators.
+#
+# 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, 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.  */
+
+       .include "utils-fpu.inc"
+
+       ###
+       ### Shared macros
+       ###
+
+       # Enable MDMX: enable the FPU w/ FR=1, then set Status.MX
+       .macro  enable_mdmx
+       enable_fpu 1
+       mfc0    $20, $12
+       or      $20, $20, (1 << 24)
+       mtc0    $20, $12
+       .endm
+
+
+       ###
+       ### .OB-format macros
+       ###
+
+       .macro ld_ob r, v
+       .data
+1:     .dword  \v
+       .previous
+       ldc1    \r, 1b
+       .endm
+
+       .macro ck_ob r, v
+       .data
+1:     .dword  \v
+       .previous
+       dmfc1   $20, \r
+       ld      $21, 1b
+       bne     $20, $21, _fail
+        nop
+       .endm
+
+       .macro ld_acc_ob h, m, l
+       ld_ob   $f20, \m
+       ld_ob   $f21, \l
+       wacl.ob $f20, $f21
+       ld_ob   $f20, \h
+       wach.ob $f20
+       .endm
+
+       .macro ck_acc_ob h, m, l
+       rach.ob $f20
+       ck_ob   $f20, \h
+       racm.ob $f20
+       ck_ob   $f20, \m
+       racl.ob $f20
+       ck_ob   $f20, \l
+       .endm
diff --git a/sim/testsuite/sim/sh/bandor.s b/sim/testsuite/sim/sh/bandor.s
new file mode 100644 (file)
index 0000000..9ada485
--- /dev/null
@@ -0,0 +1,120 @@
+# sh testcase for band, bor
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0xa5a5a5a5
+
+       start
+
+bandor_b_imm_disp12_reg:
+       set_grs_a5a5
+       # Make sure T is true to start.
+       sett
+
+       mov.l   x, r1
+
+       band.b  #0, @(3, r1)
+       bf8k    mfail
+       bor.b   #1, @(3, r1)
+       bf8k    mfail
+       band.b  #2, @(3, r1)
+       bf8k    mfail
+       bor.b   #3, @(3, r1)
+       bf8k    mfail
+
+       bor.b   #4, @(3, r1)
+       bf8k    mfail
+       band.b  #5, @(3, r1)
+       bf8k    mfail
+       bor.b   #6, @(3, r1)
+       bf8k    mfail
+       band.b  #7, @(3, r1)
+       bf8k    mfail
+
+       band.b  #0, @(2, r1)
+       bf8k    mfail
+       bor.b   #1, @(2, r1)
+       bf8k    mfail
+       band.b  #2, @(2, r1)
+       bf8k    mfail
+       bor.b   #3, @(2, r1)
+       bf8k    mfail
+
+       bra     .L2
+       nop
+
+       .align 2
+x:     .long   _x
+
+.L2:
+       bor.b   #4, @(2, r1)
+       bf8k    mfail
+       band.b  #5, @(2, r1)
+       bf8k    mfail
+       bor.b   #6, @(2, r1)
+       bf8k    mfail
+       band.b  #7, @(2, r1)
+       bf8k    mfail
+
+       band.b  #0, @(1, r1)
+       bf8k    mfail
+       bor.b   #1, @(1, r1)
+       bf8k    mfail
+       band.b  #2, @(1, r1)
+       bf8k    mfail
+       bor.b   #3, @(1, r1)
+       bf8k    mfail
+
+       bor.b   #4, @(1, r1)
+       bf8k    mfail
+       band.b  #5, @(1, r1)
+       bf8k    mfail
+       bor.b   #6, @(1, r1)
+       bf8k    mfail
+       band.b  #7, @(1, r1)
+       bf8k    mfail
+
+       band.b  #0, @(0, r1)
+       bf8k    mfail
+       bor.b   #1, @(0, r1)
+       bf8k    mfail
+       band.b  #2, @(0, r1)
+       bf8k    mfail
+       bor.b   #3, @(0, r1)
+       bf8k    mfail
+
+       bor.b   #4, @(0, r1)
+       bf8k    mfail
+       band.b  #5, @(0, r1)
+       bf8k    mfail
+       bor.b   #6, @(0, r1)
+       bf8k    mfail
+       band.b  #7, @(0, r1)
+       bf8k    mfail
+
+       assertreg _x, r1
+
+       test_gr_a5a5 r0
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+       pass
+
+       exit 0
+
+
diff --git a/sim/testsuite/sim/sh/bandornot.s b/sim/testsuite/sim/sh/bandornot.s
new file mode 100644 (file)
index 0000000..1787d0d
--- /dev/null
@@ -0,0 +1,120 @@
+# sh testcase for bandnot, bornot
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0xa5a5a5a5
+
+       start
+
+bandor_b_imm_disp12_reg:
+       set_grs_a5a5
+       # Make sure T is true to start.
+       sett
+
+       mov.l   x, r1
+
+       bandnot.b       #0, @(3, r1)
+       bt8k    mfail
+       bornot.b        #1, @(3, r1)
+       bf8k    mfail
+       bandnot.b       #2, @(3, r1)
+       bt8k    mfail
+       bornot.b        #3, @(3, r1)
+       bf8k    mfail
+
+       bornot.b        #4, @(3, r1)
+       bf8k    mfail
+       bandnot.b       #5, @(3, r1)
+       bt8k    mfail
+       bornot.b        #6, @(3, r1)
+       bf8k    mfail
+       bandnot.b       #7, @(3, r1)
+       bt8k    mfail
+
+       bandnot.b       #0, @(2, r1)
+       bt8k    mfail
+       bornot.b        #1, @(2, r1)
+       bf8k    mfail
+       bandnot.b       #2, @(2, r1)
+       bt8k    mfail
+       bornot.b        #3, @(2, r1)
+       bf8k    mfail
+
+       bra     .L2
+       nop
+
+       .align 2
+x:     .long   _x
+
+.L2:
+       bornot.b        #4, @(2, r1)
+       bf8k    mfail
+       bandnot.b       #5, @(2, r1)
+       bt8k    mfail
+       bornot.b        #6, @(2, r1)
+       bf8k    mfail
+       bandnot.b       #7, @(2, r1)
+       bt8k    mfail
+
+       bandnot.b       #0, @(1, r1)
+       bt8k    mfail
+       bornot.b        #1, @(1, r1)
+       bf8k    mfail
+       bandnot.b       #2, @(1, r1)
+       bt8k    mfail
+       bornot.b        #3, @(1, r1)
+       bf8k    mfail
+
+       bornot.b        #4, @(1, r1)
+       bf8k    mfail
+       bandnot.b       #5, @(1, r1)
+       bt8k    mfail
+       bornot.b        #6, @(1, r1)
+       bf8k    mfail
+       bandnot.b       #7, @(1, r1)
+       bt8k    mfail
+
+       bandnot.b       #0, @(0, r1)
+       bt8k    mfail
+       bornot.b        #1, @(0, r1)
+       bf8k    mfail
+       bandnot.b       #2, @(0, r1)
+       bt8k    mfail
+       bornot.b        #3, @(0, r1)
+       bf8k    mfail
+
+       bornot.b        #4, @(0, r1)
+       bf8k    mfail
+       bandnot.b       #5, @(0, r1)
+       bt8k    mfail
+       bornot.b        #6, @(0, r1)
+       bf8k    mfail
+       bandnot.b       #7, @(0, r1)
+       bt8k    mfail
+
+       assertreg _x, r1
+
+       test_gr_a5a5 r0
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+       pass
+
+       exit 0
+
+
diff --git a/sim/testsuite/sim/sh/bclr.s b/sim/testsuite/sim/sh/bclr.s
new file mode 100644 (file)
index 0000000..cbe1c7e
--- /dev/null
@@ -0,0 +1,139 @@
+# sh testcase for bclr
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0xffffffff
+_y:    .long   0x55555555
+
+       start
+
+bclr_b_imm_disp12_reg:
+       set_grs_a5a5
+       mov.l   x, r1
+
+       bclr.b  #0, @(3, r1)
+       assertmem _x, 0xfffffffe
+       bclr.b  #1, @(3, r1)
+       assertmem _x, 0xfffffffc
+       bclr.b  #2, @(3, r1)
+       assertmem _x, 0xfffffff8
+       bclr.b  #3, @(3, r1)
+       assertmem _x, 0xfffffff0
+
+       bclr.b  #4, @(3, r1)
+       assertmem _x, 0xffffffe0
+       bclr.b  #5, @(3, r1)
+       assertmem _x, 0xffffffc0
+       bclr.b  #6, @(3, r1)
+       assertmem _x, 0xffffff80
+       bclr.b  #7, @(3, r1)
+       assertmem _x, 0xffffff00
+
+       bclr.b  #0, @(2, r1)
+       assertmem _x, 0xfffffe00
+       bclr.b  #1, @(2, r1)
+       assertmem _x, 0xfffffc00
+       bclr.b  #2, @(2, r1)
+       assertmem _x, 0xfffff800
+       bclr.b  #3, @(2, r1)
+       assertmem _x, 0xfffff000
+
+       bra     .L2
+       nop
+
+       .align 2
+x:     .long   _x
+y:     .long   _y
+
+.L2:
+       bclr.b  #4, @(2, r1)
+       assertmem _x, 0xffffe000
+       bclr.b  #5, @(2, r1)
+       assertmem _x, 0xffffc000
+       bclr.b  #6, @(2, r1)
+       assertmem _x, 0xffff8000
+       bclr.b  #7, @(2, r1)
+       assertmem _x, 0xffff0000
+
+       bclr.b  #0, @(1, r1)
+       assertmem _x, 0xfffe0000
+       bclr.b  #1, @(1, r1)
+       assertmem _x, 0xfffc0000
+       bclr.b  #2, @(1, r1)
+       assertmem _x, 0xfff80000
+       bclr.b  #3, @(1, r1)
+       assertmem _x, 0xfff00000
+
+       bclr.b  #4, @(1, r1)
+       assertmem _x, 0xffe00000
+       bclr.b  #5, @(1, r1)
+       assertmem _x, 0xffc00000
+       bclr.b  #6, @(1, r1)
+       assertmem _x, 0xff800000
+       bclr.b  #7, @(1, r1)
+       assertmem _x, 0xff000000
+
+       bclr.b  #0, @(0, r1)
+       assertmem _x, 0xfe000000
+       bclr.b  #1, @(0, r1)
+       assertmem _x, 0xfc000000
+       bclr.b  #2, @(0, r1)
+       assertmem _x, 0xf8000000
+       bclr.b  #3, @(0, r1)
+       assertmem _x, 0xf0000000
+
+       bclr.b  #4, @(0, r1)
+       assertmem _x, 0xe0000000
+       bclr.b  #5, @(0, r1)
+       assertmem _x, 0xc0000000
+       bclr.b  #6, @(0, r1)
+       assertmem _x, 0x80000000
+       bclr.b  #7, @(0, r1)
+       assertmem _x, 0x00000000
+
+       assertreg _x, r1
+
+bclr_imm_reg:
+       set_greg 0xff, r1
+       bclr    #0, r1
+       assertreg 0xfe, r1
+       bclr    #1, r1
+       assertreg 0xfc, r1
+       bclr    #2, r1
+       assertreg 0xf8, r1
+       bclr    #3, r1
+       assertreg 0xf0, r1
+
+       bclr    #4, r1
+       assertreg 0xe0, r1
+       bclr    #5, r1
+       assertreg 0xc0, r1
+       bclr    #6, r1
+       assertreg 0x80, r1
+       bclr    #7, r1
+       assertreg 0x00, r1
+
+       test_gr_a5a5 r0
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+       pass
+
+       exit 0
+
+
diff --git a/sim/testsuite/sim/sh/bld.s b/sim/testsuite/sim/sh/bld.s
new file mode 100644 (file)
index 0000000..172718d
--- /dev/null
@@ -0,0 +1,121 @@
+# sh testcase for bld
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0xa5a5a5a5
+_y:    .long   0x55555555
+
+       start
+
+bld_b_imm_disp12_reg:
+       set_grs_a5a5
+       mov.l   x, r1
+
+       bld.b   #0, @(0, r1)
+       bf8k    mfail
+       bld.b   #1, @(0, r1)
+       bt8k    mfail
+       bld.b   #2, @(0, r1)
+       bf8k    mfail
+       bld.b   #3, @(0, r1)
+       bt8k    mfail
+
+       bld.b   #4, @(0, r1)
+       bt8k    mfail
+       bld.b   #5, @(0, r1)
+       bf8k    mfail
+       bld.b   #6, @(0, r1)
+       bt8k    mfail
+       bld.b   #7, @(0, r1)
+       bf8k    mfail
+
+       bld.b   #0, @(1, r1)
+       bf8k    mfail
+       bld.b   #1, @(1, r1)
+       bt8k    mfail
+       bld.b   #2, @(1, r1)
+       bf8k    mfail
+       bld.b   #3, @(1, r1)
+       bt8k    mfail
+
+       bld.b   #4, @(1, r1)
+       bt8k    mfail
+       bld.b   #5, @(1, r1)
+       bf8k    mfail
+       bld.b   #6, @(1, r1)
+       bt8k    mfail
+       bld.b   #7, @(1, r1)
+       bf8k    mfail
+
+       bld.b   #0, @(2, r1)
+       bf8k    mfail
+       bld.b   #1, @(2, r1)
+       bt8k    mfail
+       bld.b   #2, @(2, r1)
+       bf8k    mfail
+       bld.b   #3, @(2, r1)
+       bt8k    mfail
+
+       bld.b   #4, @(2, r1)
+       bt8k    mfail
+       bld.b   #5, @(2, r1)
+       bf8k    mfail
+       bld.b   #6, @(2, r1)
+       bt8k    mfail
+       bld.b   #7, @(2, r1)
+       bf8k    mfail
+
+       bld.b   #0, @(3, r1)
+       bf8k    mfail
+       bld.b   #1, @(3, r1)
+       bt8k    mfail
+       bld.b   #2, @(3, r1)
+       bf8k    mfail
+       bld.b   #3, @(3, r1)
+       bt8k    mfail
+
+       bld.b   #4, @(3, r1)
+       bt8k    mfail
+       bld.b   #5, @(3, r1)
+       bf8k    mfail
+       bld.b   #6, @(3, r1)
+       bt8k    mfail
+       bld.b   #7, @(3, r1)
+       bf8k    mfail
+
+       assertreg _x, r1
+
+bld_imm_reg:
+       set_greg 0xa5a5a5a5, r1
+       bld     #0, r1
+       bf8k    mfail
+       bld     #1, r1
+       bt8k    mfail
+       bld     #2, r1
+       bf8k    mfail
+       bld     #3, r1
+       bt8k    mfail
+
+       bld     #4, r1
+       bt8k    mfail
+       bld     #5, r1
+       bf8k    mfail
+       bld     #6, r1
+       bt8k    mfail
+       bld     #7, r1
+       bf8k    mfail
+
+       test_grs_a5a5
+
+       pass
+
+       exit 0
+
+       .align 2
+x:     .long   _x
+y:     .long   _y
+
diff --git a/sim/testsuite/sim/sh/bldnot.s b/sim/testsuite/sim/sh/bldnot.s
new file mode 100644 (file)
index 0000000..eda87de
--- /dev/null
@@ -0,0 +1,102 @@
+# sh testcase for bldnot
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0xa5a5a5a5
+_y:    .long   0x55555555
+
+       start
+
+bldnot_b_imm_disp12_reg:
+       set_grs_a5a5
+       mov.l   x, r1
+
+       bldnot.b        #0, @(0, r1)
+       bt8k    mfail
+       bldnot.b        #1, @(0, r1)
+       bf8k    mfail
+       bldnot.b        #2, @(0, r1)
+       bt8k    mfail
+       bldnot.b        #3, @(0, r1)
+       bf8k    mfail
+
+       bldnot.b        #4, @(0, r1)
+       bf8k    mfail
+       bldnot.b        #5, @(0, r1)
+       bt8k    mfail
+       bldnot.b        #6, @(0, r1)
+       bf8k    mfail
+       bldnot.b        #7, @(0, r1)
+       bt8k    mfail
+
+       bldnot.b        #0, @(1, r1)
+       bt8k    mfail
+       bldnot.b        #1, @(1, r1)
+       bf8k    mfail
+       bldnot.b        #2, @(1, r1)
+       bt8k    mfail
+       bldnot.b        #3, @(1, r1)
+       bf8k    mfail
+
+       bldnot.b        #4, @(1, r1)
+       bf8k    mfail
+       bldnot.b        #5, @(1, r1)
+       bt8k    mfail
+       bldnot.b        #6, @(1, r1)
+       bf8k    mfail
+       bldnot.b        #7, @(1, r1)
+       bt8k    mfail
+
+       bldnot.b        #0, @(2, r1)
+       bt8k    mfail
+       bldnot.b        #1, @(2, r1)
+       bf8k    mfail
+       bldnot.b        #2, @(2, r1)
+       bt8k    mfail
+       bldnot.b        #3, @(2, r1)
+       bf8k    mfail
+
+       bldnot.b        #4, @(2, r1)
+       bf8k    mfail
+       bldnot.b        #5, @(2, r1)
+       bt8k    mfail
+       bldnot.b        #6, @(2, r1)
+       bf8k    mfail
+       bldnot.b        #7, @(2, r1)
+       bt8k    mfail
+
+       bldnot.b        #0, @(3, r1)
+       bt8k    mfail
+       bldnot.b        #1, @(3, r1)
+       bf8k    mfail
+       bldnot.b        #2, @(3, r1)
+       bt8k    mfail
+       bldnot.b        #3, @(3, r1)
+       bf8k    mfail
+
+       bldnot.b        #4, @(3, r1)
+       bf8k    mfail
+       bldnot.b        #5, @(3, r1)
+       bt8k    mfail
+       bldnot.b        #6, @(3, r1)
+       bf8k    mfail
+       bldnot.b        #7, @(3, r1)
+       bt8k    mfail
+
+       assertreg _x, r1
+       set_greg 0xa5a5a5a5, r1
+
+       test_grs_a5a5
+
+       pass
+
+       exit 0
+
+       .align 2
+x:     .long   _x
+y:     .long   _y
+
diff --git a/sim/testsuite/sim/sh/bset.s b/sim/testsuite/sim/sh/bset.s
new file mode 100644 (file)
index 0000000..13ae246
--- /dev/null
@@ -0,0 +1,139 @@
+# sh testcase for bset
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0
+_y:    .long   0x55555555
+
+       start
+
+bset_b_imm_disp12_reg:
+       set_grs_a5a5
+       mov.l   x, r1
+
+       bset.b  #0, @(3, r1)
+       assertmem _x, 0x1
+       bset.b  #1, @(3, r1)
+       assertmem _x, 0x3
+       bset.b  #2, @(3, r1)
+       assertmem _x, 0x7
+       bset.b  #3, @(3, r1)
+       assertmem _x, 0xf
+
+       bset.b  #4, @(3, r1)
+       assertmem _x, 0x1f
+       bset.b  #5, @(3, r1)
+       assertmem _x, 0x3f
+       bset.b  #6, @(3, r1)
+       assertmem _x, 0x7f
+       bset.b  #7, @(3, r1)
+       assertmem _x, 0xff
+
+       bset.b  #0, @(2, r1)
+       assertmem _x, 0x1ff
+       bset.b  #1, @(2, r1)
+       assertmem _x, 0x3ff
+       bset.b  #2, @(2, r1)
+       assertmem _x, 0x7ff
+       bset.b  #3, @(2, r1)
+       assertmem _x, 0xfff
+
+       bra     .L2
+       nop
+
+       .align 2
+x:     .long   _x
+y:     .long   _y
+
+.L2:
+       bset.b  #4, @(2, r1)
+       assertmem _x, 0x1fff
+       bset.b  #5, @(2, r1)
+       assertmem _x, 0x3fff
+       bset.b  #6, @(2, r1)
+       assertmem _x, 0x7fff
+       bset.b  #7, @(2, r1)
+       assertmem _x, 0xffff
+
+       bset.b  #0, @(1, r1)
+       assertmem _x, 0x1ffff
+       bset.b  #1, @(1, r1)
+       assertmem _x, 0x3ffff
+       bset.b  #2, @(1, r1)
+       assertmem _x, 0x7ffff
+       bset.b  #3, @(1, r1)
+       assertmem _x, 0xfffff
+
+       bset.b  #4, @(1, r1)
+       assertmem _x, 0x1fffff
+       bset.b  #5, @(1, r1)
+       assertmem _x, 0x3fffff
+       bset.b  #6, @(1, r1)
+       assertmem _x, 0x7fffff
+       bset.b  #7, @(1, r1)
+       assertmem _x, 0xffffff
+
+       bset.b  #0, @(0, r1)
+       assertmem _x, 0x1ffffff
+       bset.b  #1, @(0, r1)
+       assertmem _x, 0x3ffffff
+       bset.b  #2, @(0, r1)
+       assertmem _x, 0x7ffffff
+       bset.b  #3, @(0, r1)
+       assertmem _x, 0xfffffff
+
+       bset.b  #4, @(0, r1)
+       assertmem _x, 0x1fffffff
+       bset.b  #5, @(0, r1)
+       assertmem _x, 0x3fffffff
+       bset.b  #6, @(0, r1)
+       assertmem _x, 0x7fffffff
+       bset.b  #7, @(0, r1)
+       assertmem _x, 0xffffffff
+
+       assertreg _x, r1
+
+bset_imm_reg:
+       set_greg 0, r1
+       bset    #0, r1
+       assertreg 0x1, r1
+       bset    #1, r1
+       assertreg 0x3, r1
+       bset    #2, r1
+       assertreg 0x7, r1
+       bset    #3, r1
+       assertreg 0xf, r1
+
+       bset    #4, r1
+       assertreg 0x1f, r1
+       bset    #5, r1
+       assertreg 0x3f, r1
+       bset    #6, r1
+       assertreg 0x7f, r1
+       bset    #7, r1
+       assertreg 0xff, r1
+
+       test_gr_a5a5 r0
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+       pass
+
+       exit 0
+
+
diff --git a/sim/testsuite/sim/sh/bst.s b/sim/testsuite/sim/sh/bst.s
new file mode 100644 (file)
index 0000000..e8b6d65
--- /dev/null
@@ -0,0 +1,142 @@
+# sh testcase for bst
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0
+_y:    .long   0x55555555
+
+       start
+
+bst_b_imm_disp12_reg:
+       set_grs_a5a5
+       # Make sure T is true to start.
+       sett
+
+       mov.l   x, r1
+
+       bst.b   #0, @(3, r1)
+       assertmem _x, 0x1
+       bst.b   #1, @(3, r1)
+       assertmem _x, 0x3
+       bst.b   #2, @(3, r1)
+       assertmem _x, 0x7
+       bst.b   #3, @(3, r1)
+       assertmem _x, 0xf
+
+       bst.b   #4, @(3, r1)
+       assertmem _x, 0x1f
+       bst.b   #5, @(3, r1)
+       assertmem _x, 0x3f
+       bst.b   #6, @(3, r1)
+       assertmem _x, 0x7f
+       bst.b   #7, @(3, r1)
+       assertmem _x, 0xff
+
+       bst.b   #0, @(2, r1)
+       assertmem _x, 0x1ff
+       bst.b   #1, @(2, r1)
+       assertmem _x, 0x3ff
+       bst.b   #2, @(2, r1)
+       assertmem _x, 0x7ff
+       bst.b   #3, @(2, r1)
+       assertmem _x, 0xfff
+
+       bra     .L2
+       nop
+
+       .align 2
+x:     .long   _x
+y:     .long   _y
+
+.L2:
+       bst.b   #4, @(2, r1)
+       assertmem _x, 0x1fff
+       bst.b   #5, @(2, r1)
+       assertmem _x, 0x3fff
+       bst.b   #6, @(2, r1)
+       assertmem _x, 0x7fff
+       bst.b   #7, @(2, r1)
+       assertmem _x, 0xffff
+
+       bst.b   #0, @(1, r1)
+       assertmem _x, 0x1ffff
+       bst.b   #1, @(1, r1)
+       assertmem _x, 0x3ffff
+       bst.b   #2, @(1, r1)
+       assertmem _x, 0x7ffff
+       bst.b   #3, @(1, r1)
+       assertmem _x, 0xfffff
+
+       bst.b   #4, @(1, r1)
+       assertmem _x, 0x1fffff
+       bst.b   #5, @(1, r1)
+       assertmem _x, 0x3fffff
+       bst.b   #6, @(1, r1)
+       assertmem _x, 0x7fffff
+       bst.b   #7, @(1, r1)
+       assertmem _x, 0xffffff
+
+       bst.b   #0, @(0, r1)
+       assertmem _x, 0x1ffffff
+       bst.b   #1, @(0, r1)
+       assertmem _x, 0x3ffffff
+       bst.b   #2, @(0, r1)
+       assertmem _x, 0x7ffffff
+       bst.b   #3, @(0, r1)
+       assertmem _x, 0xfffffff
+
+       bst.b   #4, @(0, r1)
+       assertmem _x, 0x1fffffff
+       bst.b   #5, @(0, r1)
+       assertmem _x, 0x3fffffff
+       bst.b   #6, @(0, r1)
+       assertmem _x, 0x7fffffff
+       bst.b   #7, @(0, r1)
+       assertmem _x, 0xffffffff
+
+       assertreg _x, r1
+
+bst_imm_reg:
+       set_greg 0, r1
+       bst     #0, r1
+       assertreg 0x1, r1
+       bst     #1, r1
+       assertreg 0x3, r1
+       bst     #2, r1
+       assertreg 0x7, r1
+       bst     #3, r1
+       assertreg 0xf, r1
+
+       bst     #4, r1
+       assertreg 0x1f, r1
+       bst     #5, r1
+       assertreg 0x3f, r1
+       bst     #6, r1
+       assertreg 0x7f, r1
+       bst     #7, r1
+       assertreg 0xff, r1
+
+       test_gr_a5a5 r0
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+       pass
+
+       exit 0
+
+
diff --git a/sim/testsuite/sim/sh/bxor.s b/sim/testsuite/sim/sh/bxor.s
new file mode 100644 (file)
index 0000000..abedd38
--- /dev/null
@@ -0,0 +1,120 @@
+# sh testcase for bxor
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .align 2
+_x:    .long   0xa5a5a5a5
+
+       start
+
+bxor_b_imm_disp12_reg:
+       set_grs_a5a5
+       # Make sure T is true to start.
+       sett
+
+       mov.l   x, r1
+
+       bxor.b  #0, @(3, r1)
+       bt8k    mfail
+       bxor.b  #1, @(3, r1)
+       bt8k    mfail
+       bxor.b  #2, @(3, r1)
+       bf8k    mfail
+       bxor.b  #3, @(3, r1)
+       bf8k    mfail
+
+       bxor.b  #4, @(3, r1)
+       bf8k    mfail
+       bxor.b  #5, @(3, r1)
+       bt8k    mfail
+       bxor.b  #6, @(3, r1)
+       bt8k    mfail
+       bxor.b  #7, @(3, r1)
+       bf8k    mfail
+
+       bxor.b  #0, @(2, r1)
+       bt8k    mfail
+       bxor.b  #1, @(2, r1)
+       bt8k    mfail
+       bxor.b  #2, @(2, r1)
+       bf8k    mfail
+       bxor.b  #3, @(2, r1)
+       bf8k    mfail
+
+       bra     .L2
+       nop
+
+       .align 2
+x:     .long   _x
+
+.L2:
+       bxor.b  #4, @(2, r1)
+       bf8k    mfail
+       bxor.b  #5, @(2, r1)
+       bt8k    mfail
+       bxor.b  #6, @(2, r1)
+       bt8k    mfail
+       bxor.b  #7, @(2, r1)
+       bf8k    mfail
+
+       bxor.b  #0, @(1, r1)
+       bt8k    mfail
+       bxor.b  #1, @(1, r1)
+       bt8k    mfail
+       bxor.b  #2, @(1, r1)
+       bf8k    mfail
+       bxor.b  #3, @(1, r1)
+       bf8k    mfail
+
+       bxor.b  #4, @(1, r1)
+       bf8k    mfail
+       bxor.b  #5, @(1, r1)
+       bt8k    mfail
+       bxor.b  #6, @(1, r1)
+       bt8k    mfail
+       bxor.b  #7, @(1, r1)
+       bf8k    mfail
+
+       bxor.b  #0, @(0, r1)
+       bt8k    mfail
+       bxor.b  #1, @(0, r1)
+       bt8k    mfail
+       bxor.b  #2, @(0, r1)
+       bf8k    mfail
+       bxor.b  #3, @(0, r1)
+       bf8k    mfail
+
+       bxor.b  #4, @(0, r1)
+       bf8k    mfail
+       bxor.b  #5, @(0, r1)
+       bt8k    mfail
+       bxor.b  #6, @(0, r1)
+       bt8k    mfail
+       bxor.b  #7, @(0, r1)
+       bf8k    mfail
+
+       assertreg _x, r1
+
+       test_gr_a5a5 r0
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+       pass
+
+       exit 0
+
+
diff --git a/sim/testsuite/sim/sh/clip.s b/sim/testsuite/sim/sh/clip.s
new file mode 100644 (file)
index 0000000..12770c3
--- /dev/null
@@ -0,0 +1,89 @@
+# sh testcase for clips, clipu
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       start
+
+clips_b:
+       set_grs_a5a5
+       clips.b r1
+       test_gr0_a5a5
+       assertreg 0xffffff80 r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+clipu_b:
+       set_grs_a5a5
+       clipu.b r1
+       test_gr0_a5a5
+       assertreg 0xff r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+       
+clips_w:
+       set_grs_a5a5
+       clips.w r1
+       test_gr0_a5a5
+       assertreg 0xffff8000 r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+clipu_w:
+       set_grs_a5a5
+       clipu.w r1
+       test_gr0_a5a5
+       assertreg 0xffff r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+       
+       pass
+
+       exit 0
+
diff --git a/sim/testsuite/sim/sh/div.s b/sim/testsuite/sim/sh/div.s
new file mode 100644 (file)
index 0000000..8293c21
--- /dev/null
@@ -0,0 +1,199 @@
+# sh testcase for divs and divu
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       start
+
+divs_1:        ! divide by one
+       set_grs_a5a5
+       mov     #1, r0
+       divs    r0, r1
+       assertreg0   1
+       test_gr_a5a5 r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+divs_2:        ! divide by two
+       set_grs_a5a5
+       mov     #2, r0
+       divs    r0, r1
+       assertreg0   2
+       assertreg 0xd2d2d2d3, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+divs_3:        ! divide by three
+       set_grs_a5a5
+       mov     #3, r0
+       divs    r0, r1
+       assertreg0   3
+       assertreg 0xe1e1e1e2, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+divs_0:        ! divide by zero
+       set_grs_a5a5
+       mov     #0, r0
+       divs    r0, r1
+       assertreg0   0
+       assertreg 0x7fffffff, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+divs_o:        ! divide signed overflow
+       set_grs_a5a5
+       mov     #16, r0
+       movi20  #0x8000, r1
+       shad    r0, r1  ! r1 == 0x80000000
+       mov     #-1, r0
+       divs    r0, r1
+       assertreg0   -1
+       assertreg 0x7fffffff, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+
+divu_1:        ! divide by one, unsigned
+       set_grs_a5a5
+       mov     #1, r0
+       divu    r0, r1
+       assertreg0   1
+       test_gr_a5a5 r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+divu_2:        ! divide by two, unsigned
+       set_grs_a5a5
+       mov     #2, r0
+       divu    r0, r1
+       assertreg0   2
+       assertreg 0x52d2d2d2, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+divu_3:        ! divide by three, unsigned
+       set_grs_a5a5
+       mov     #3, r0
+       divu    r0, r1
+       assertreg0   3
+       assertreg 0x37373737, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+divu_0:        ! divide by zero, unsigned
+       set_grs_a5a5
+       mov     #0, r0
+       divu    r0, r1
+       assertreg0   0
+       assertreg 0xffffffff, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+
+       pass
+
+       exit 0
+
+       
\ No newline at end of file
diff --git a/sim/testsuite/sim/sh/fail.s b/sim/testsuite/sim/sh/fail.s
new file mode 100644 (file)
index 0000000..0ffb0b2
--- /dev/null
@@ -0,0 +1,13 @@
+# sh testcase, fail
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       start
+       
+       fail
+
+       exit 0
+
diff --git a/sim/testsuite/sim/sh/fsca.s b/sim/testsuite/sim/sh/fsca.s
new file mode 100644 (file)
index 0000000..90df6c9
--- /dev/null
@@ -0,0 +1,97 @@
+# sh testcase for fsca
+# mach: sh
+# as(sh):      -defsym sim_cpu=0
+
+       .include "testutils.inc"
+
+       start
+fsca:
+       set_grs_a5a5
+       set_fprs_a5a5
+       # Start with angle zero
+       mov.l   zero, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i 0, fr2
+       assert_fpreg_i 1, fr3
+       
+       mov.l   plus_90, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i 1, fr2
+       assert_fpreg_i 0, fr3
+       
+       mov.l   plus_180, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i 0, fr2
+       assert_fpreg_i -1, fr3
+       
+       mov.l   plus_270, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i -1, fr2
+       assert_fpreg_i 0, fr3
+       
+       mov.l   plus_360, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i 0, fr2
+       assert_fpreg_i 1, fr3
+
+       mov.l   minus_90, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i -1, fr2
+       assert_fpreg_i 0, fr3
+       
+       mov.l   minus_180, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i 0, fr2
+       assert_fpreg_i -1, fr3
+       
+       mov.l   minus_270, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i 1, fr2
+       assert_fpreg_i 0, fr3
+       
+       mov.l   minus_360, r0
+       lds     r0, fpul
+       fsca    fpul, dr2
+       assert_fpreg_i 0, fr2
+       assert_fpreg_i 1, fr3
+
+       assertreg0      0xffff0000
+       set_greg        0xa5a5a5a5, r0
+       test_grs_a5a5
+       test_fpr_a5a5   fr0
+       test_fpr_a5a5   fr1
+       test_fpr_a5a5   fr4
+       test_fpr_a5a5   fr5
+       test_fpr_a5a5   fr6
+       test_fpr_a5a5   fr7
+       test_fpr_a5a5   fr8
+       test_fpr_a5a5   fr9
+       test_fpr_a5a5   fr10
+       test_fpr_a5a5   fr11
+       test_fpr_a5a5   fr12
+       test_fpr_a5a5   fr13
+       test_fpr_a5a5   fr14
+       test_fpr_a5a5   fr15
+       pass
+       exit 0
+
+               .align 2
+zero:          .long   0
+one_bitty:     .long   1
+plus_90:       .long   0x04000
+plus_180:      .long   0x08000
+plus_270:      .long   0x0c000
+plus_360:      .long   0x10000
+minus_90:      .long   0xffffc000
+minus_180:     .long   0xffff8000
+minus_270:     .long   0xffff4000
+minus_360:     .long   0xffff0000
+minus_1_bitty: .long   0xffffffff
diff --git a/sim/testsuite/sim/sh/fsrra.s b/sim/testsuite/sim/sh/fsrra.s
new file mode 100644 (file)
index 0000000..fdd2235
--- /dev/null
@@ -0,0 +1,62 @@
+# sh testcase for fsrra
+# mach: sh
+# as(sh):      -defsym sim_cpu=0
+
+       .include "testutils.inc"
+
+       start
+fsrra_single:
+       set_grs_a5a5
+       set_fprs_a5a5
+       # 1/sqrt(0.0) = +infinity.
+       fldi0   fr0
+       fsrra   fr0
+       assert_fpreg_x  0x7f800000, fr0
+
+       # 1/sqrt(1.0) = 1.0.
+       fldi1   fr0
+       fsrra   fr0
+       assert_fpreg_i  1, fr0
+
+       # 1/sqrt(4.0) = 1/2.0
+       fldi1   fr0
+       # Double it.
+       fadd    fr0, fr0
+       # Double it again.
+       fadd    fr0, fr0
+       fsrra   fr0
+       fldi1   fr2
+       # Double it.
+       fadd    fr2, fr2
+       fldi1   fr1
+       # Divide
+       fdiv    fr2, fr1
+       fcmp/eq fr0, fr1
+       bt      .L2
+       fail
+.L2:
+       # Double-check (pun intended)
+       fadd    fr0, fr0
+       assert_fpreg_i  1, fr0
+       fadd    fr1, fr1
+       assert_fpreg_i  1, fr1
+
+       # And make sure the rest of the regs are un-affected.
+       assert_fpreg_i  2, fr2
+       test_fpr_a5a5   fr3
+       test_fpr_a5a5   fr4
+       test_fpr_a5a5   fr5
+       test_fpr_a5a5   fr6
+       test_fpr_a5a5   fr7
+       test_fpr_a5a5   fr8
+       test_fpr_a5a5   fr9
+       test_fpr_a5a5   fr10
+       test_fpr_a5a5   fr11
+       test_fpr_a5a5   fr12
+       test_fpr_a5a5   fr13
+       test_fpr_a5a5   fr14
+       test_fpr_a5a5   fr15
+       test_grs_a5a5
+
+       pass
+       exit 0
diff --git a/sim/testsuite/sim/sh/mov.s b/sim/testsuite/sim/sh/mov.s
new file mode 100644 (file)
index 0000000..37fef51
--- /dev/null
@@ -0,0 +1,118 @@
+# sh testcase for all mov.[bwl] instructions
+# mach: sh
+# as(sh):      -defsym sim_cpu=0
+
+       .include "testutils.inc"
+
+       .align 2
+_lsrc: .long   0x55555555
+_wsrc: .long   0x55550000
+_bsrc: .long   0x55000000
+
+       .align 2
+_ldst: .long   0
+_wdst: .long   0
+_bdst: .long   0
+
+
+       start
+
+movb_disp12_reg:       # Test 8-bit @(disp12,gr) -> gr
+       set_grs_a5a5
+       mov.l   bsrc, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       mov.b   @(444,r1), r2
+
+       assertreg _bsrc-444, r1
+       assertreg 0x55, r2
+
+movb_reg_disp12:       # Test 8-bit gr -> @(disp12,gr)
+       set_grs_a5a5
+       mov.l   bdst, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       mov.b   r2, @(444,r1)
+
+       assertreg _bdst-444, r1
+       assertmem _bdst, 0xa5000000
+
+movw_disp12_reg:       # Test 16-bit @(disp12,gr) -> gr
+       set_grs_a5a5
+       mov.l   wsrc, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       mov.w   @(444,r1), r2
+
+       assertreg _wsrc-444, r1
+       assertreg 0x5555, r2
+
+movw_reg_disp12:       # Test 16-bit gr -> @(disp12,gr)
+       set_grs_a5a5
+       mov.l   wdst, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       mov.w   r2, @(444,r1)
+
+       assertreg _wdst-444, r1
+       assertmem _wdst, 0xa5a50000
+
+movl_disp12_reg:       # Test 32-bit @(disp12,gr) -> gr
+       set_grs_a5a5
+       mov.l   lsrc, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       mov.l   @(444,r1), r2
+
+       assertreg _lsrc-444, r1
+       assertreg 0x55555555, r2
+
+movl_reg_disp12:       # Test 32-bit gr -> @(disp12,gr)
+       set_grs_a5a5
+       mov.l   ldst, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       add     #-111, r1
+       mov.l   r2, @(444,r1)
+
+       assertreg _ldst-444, r1
+       assertmem _ldst, 0xa5a5a5a5
+
+       test_gr_a5a5 r0
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+       pass
+
+       exit 0
+
+lsrc:  .long _lsrc
+wsrc:  .long _wsrc
+bsrc:  .long _bsrc
+
+ldst:  .long _ldst
+wdst:  .long _wdst
+bdst:  .long _bdst
+
diff --git a/sim/testsuite/sim/sh/mulr.s b/sim/testsuite/sim/sh/mulr.s
new file mode 100644 (file)
index 0000000..1e755ab
--- /dev/null
@@ -0,0 +1,162 @@
+# sh testcase for mulr
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       start
+
+mulr_1:        ! multiply by one
+       set_grs_a5a5
+       mov     #1, r0
+       mulr    r0, r1
+       assertreg0   1
+       test_gr_a5a5 r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+mulr_2:        ! multiply by two
+       set_grs_a5a5
+       mov     #2, r0
+       mov     #12, r1
+       mulr    r0, r1
+       assertreg0   2
+       assertreg 24, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+mulr_3:        ! multiply five by five
+       set_grs_a5a5
+       mov     #5, r0
+       mov     #5, r1
+       mulr    r0, r1
+       assertreg0   5
+       assertreg 25, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+
+mulr_4:        ! multiply 127 by 127
+       set_grs_a5a5
+       mov     #127, r0
+       mov     #127, r1
+       mulr    r0, r1
+       assertreg0   127
+       assertreg 0x3f01, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+mulr_5:        ! multiply -1 by -1
+       set_grs_a5a5
+       mov     #-1, r0
+       mov     #-1, r1
+       mulr    r0, r1
+       assertreg0   -1
+       assertreg 1, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+mulr_6:        ! multiply 46340 by 46340
+       set_grs_a5a5
+       movi20  #46340, r0
+       movi20  #46340, r1
+       mulr    r0, r1
+       assertreg0   46340
+       assertreg 0x7ffea810, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+mulr_7:        ! multiply 7ffff by 7ffff (overflow)
+       set_grs_a5a5
+       movi20  #0x7ffff, r0
+       movi20  #0x7ffff, r1
+       mulr    r0, r1
+       assertreg0   0x7ffff
+       assertreg 0xfff00001, r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+
+       pass
+
+       exit 0
+
+       
\ No newline at end of file
diff --git a/sim/testsuite/sim/sh/pass.s b/sim/testsuite/sim/sh/pass.s
new file mode 100644 (file)
index 0000000..cc3bbcc
--- /dev/null
@@ -0,0 +1,14 @@
+# sh testcase, pass
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       start
+       set_grs_a5a5
+       test_grs_a5a5
+       pass
+
+       exit 0
+
diff --git a/sim/testsuite/sim/sh/pushpop.s b/sim/testsuite/sim/sh/pushpop.s
new file mode 100644 (file)
index 0000000..9ee5bfd
--- /dev/null
@@ -0,0 +1,146 @@
+# sh testcase for push/pop (mov,movml,movmu...) insns.
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       start
+movml_1:
+       set_greg 0, r0
+       set_greg 1, r1
+       set_greg 2, r2
+       set_greg 3, r3
+       set_greg 4, r4
+       set_greg 5, r5
+       set_greg 6, r6
+       set_greg 7, r7
+       set_greg 8, r8
+       set_greg 9, r9
+       set_greg 10, r10
+       set_greg 11, r11
+       set_greg 12, r12
+       set_greg 13, r13
+       set_greg 14, r14
+       set_sreg 15, pr
+
+       movml.l         r15,@-r15
+
+       assertmem       stackt-4,  15
+       assertmem       stackt-8,  14
+       assertmem       stackt-12, 13
+       assertmem       stackt-16, 12
+       assertmem       stackt-20, 11
+       assertmem       stackt-24, 10
+       assertmem       stackt-28, 9
+       assertmem       stackt-32, 8
+       assertmem       stackt-36, 7
+       assertmem       stackt-40, 6
+       assertmem       stackt-44, 5
+       assertmem       stackt-48, 4
+       assertmem       stackt-52, 3
+       assertmem       stackt-56, 2
+       assertmem       stackt-60, 1
+       assertmem       stackt-64, 0
+
+       assertreg0      0
+       assertreg       1, r1
+       assertreg       2, r2
+       assertreg       3, r3
+       assertreg       4, r4
+       assertreg       5, r5
+       assertreg       6, r6
+       assertreg       7, r7
+       assertreg       8, r8
+       assertreg       9, r9
+       assertreg       10, r10
+       assertreg       11, r11
+       assertreg       12, r12
+       assertreg       13, r13
+       assertreg       14, r14
+       mov             r15, r0
+       assertreg0      stackt-64
+
+movml_2:
+       set_grs_a5a5
+       movml.l         @r15+, r15
+       assert_sreg     15, pr
+       assertreg0      0
+       assertreg       1, r1
+       assertreg       2, r2
+       assertreg       3, r3
+       assertreg       4, r4
+       assertreg       5, r5
+       assertreg       6, r6
+       assertreg       7, r7
+       assertreg       8, r8
+       assertreg       9, r9
+       assertreg       10, r10
+       assertreg       11, r11
+       assertreg       12, r12
+       assertreg       13, r13
+       assertreg       14, r14
+       mov             r15, r0
+       assertreg0      stackt
+
+movmu_1:
+       set_grs_a5a5
+       add     #1,r14
+       add     #2,r13
+       add     #3,r12
+       set_sreg 0xa5a5,pr
+
+       movmu.l r12,@-r15
+
+       assert_sreg     0xa5a5,pr
+       assertreg       0xa5a5a5a6, r14
+       assertreg       0xa5a5a5a7, r13
+       assertreg       0xa5a5a5a8, r12
+       test_gr_a5a5    r11
+       test_gr_a5a5    r10
+       test_gr_a5a5    r9
+       test_gr_a5a5    r8
+       test_gr_a5a5    r7
+       test_gr_a5a5    r6
+       test_gr_a5a5    r5
+       test_gr_a5a5    r4
+       test_gr_a5a5    r3
+       test_gr_a5a5    r2
+       test_gr_a5a5    r1
+       test_gr_a5a5    r0
+       mov     r15, r0
+       assertreg       stackt-16, r0
+
+       assertmem       stackt-4, 0xa5a5
+       assertmem       stackt-8, 0xa5a5a5a6
+       assertmem       stackt-12, 0xa5a5a5a7
+       assertmem       stackt-16, 0xa5a5a5a8
+
+movmu_2:
+       set_grs_a5a5
+       movmu.l         @r15+,r12
+
+       assert_sreg     0xa5a5, pr
+       assertreg       0xa5a5a5a6, r14
+       assertreg       0xa5a5a5a7, r13
+       assertreg       0xa5a5a5a8, r12
+       test_gr_a5a5    r11
+       test_gr_a5a5    r10
+       test_gr_a5a5    r9
+       test_gr_a5a5    r8
+       test_gr_a5a5    r7
+       test_gr_a5a5    r6
+       test_gr_a5a5    r5
+       test_gr_a5a5    r4
+       test_gr_a5a5    r3
+       test_gr_a5a5    r2
+       test_gr_a5a5    r1
+       test_gr_a5a5    r0
+       mov     r15, r0
+       assertreg       stackt, r0
+
+       pass
+
+       exit 0
+
+       
\ No newline at end of file
diff --git a/sim/testsuite/sim/sh/resbank.s b/sim/testsuite/sim/sh/resbank.s
new file mode 100644 (file)
index 0000000..33801b8
--- /dev/null
@@ -0,0 +1,268 @@
+# sh testcase for ldbank stbank resbank
+# mach:         all
+# as(sh):      -defsym sim_cpu=0
+# as(shdsp):   -defsym sim_cpu=1 -dsp 
+
+       .include "testutils.inc"
+
+       .macro  SEND reg bankno regno
+       set_greg ((\bankno << 7) + (\regno << 2)), \reg
+       .endm
+
+       start
+
+stbank_1:
+       set_grs_a5a5
+       mov     #0, r0
+       SEND    r1, 0, 0
+       stbank  r0, @r1
+       mov     #1, r0
+       SEND    r1, 0, 1
+       stbank  r0, @r1
+       mov     #2, r0
+       SEND    r1, 0, 2
+       stbank  r0, @r1
+       mov     #3, r0
+       SEND    r1, 0, 3
+       stbank  r0, @r1
+       mov     #4, r0
+       SEND    r1, 0, 4
+       stbank  r0, @r1
+       mov     #5, r0
+       SEND    r1, 0, 5
+       stbank  r0, @r1
+       mov     #6, r0
+       SEND    r1, 0, 6
+       stbank  r0, @r1
+       mov     #7, r0
+       SEND    r1, 0, 7
+       stbank  r0, @r1
+       mov     #8, r0
+       SEND    r1, 0, 8
+       stbank  r0, @r1
+       mov     #9, r0
+       SEND    r1, 0, 9
+       stbank  r0, @r1
+       mov     #10, r0
+       SEND    r1, 0, 10
+       stbank  r0, @r1
+       mov     #11, r0
+       SEND    r1, 0, 11
+       stbank  r0, @r1
+       mov     #12, r0
+       SEND    r1, 0, 12
+       stbank  r0, @r1
+       mov     #13, r0
+       SEND    r1, 0, 13
+       stbank  r0, @r1
+       mov     #14, r0
+       SEND    r1, 0, 14
+       stbank  r0, @r1
+       mov     #15, r0
+       SEND    r1, 0, 15
+       stbank  r0, @r1
+       mov     #16, r0
+       SEND    r1, 0, 16
+       stbank  r0, @r1
+       mov     #17, r0
+       SEND    r1, 0, 17
+       stbank  r0, @r1
+       mov     #18, r0
+       SEND    r1, 0, 18
+       stbank  r0, @r1
+       mov     #19, r0
+       SEND    r1, 0, 19
+       stbank  r0, @r1
+
+       assertreg0      19
+       assertreg       19 << 2, r1
+       test_gr_a5a5    r2
+       test_gr_a5a5    r3
+       test_gr_a5a5    r4
+       test_gr_a5a5    r5
+       test_gr_a5a5    r6
+       test_gr_a5a5    r7
+       test_gr_a5a5    r8
+       test_gr_a5a5    r9
+       test_gr_a5a5    r10
+       test_gr_a5a5    r11
+       test_gr_a5a5    r12
+       test_gr_a5a5    r13
+       test_gr_a5a5    r14
+
+ldbank_1:
+       set_grs_a5a5
+       SEND    r1, 0, 0
+       ldbank  @r1, r0
+       assertreg0 0
+       SEND    r1, 0, 1
+       ldbank  @r1, r0
+       assertreg0 1
+       SEND    r1, 0, 2
+       ldbank  @r1, r0
+       assertreg0 2
+       SEND    r1, 0, 3
+       ldbank  @r1, r0
+       assertreg0 3
+       SEND    r1, 0, 4
+       ldbank  @r1, r0
+       assertreg0 4
+       SEND    r1, 0, 5
+       ldbank  @r1, r0
+       assertreg0 5
+       SEND    r1, 0, 6
+       ldbank  @r1, r0
+       assertreg0 6
+       SEND    r1, 0, 7
+       ldbank  @r1, r0
+       assertreg0 7
+       SEND    r1, 0, 8
+       ldbank  @r1, r0
+       assertreg0 8
+       SEND    r1, 0, 9
+       ldbank  @r1, r0
+       assertreg0 9
+       SEND    r1, 0, 10
+       ldbank  @r1, r0
+       assertreg0 10
+       SEND    r1, 0, 11
+       ldbank  @r1, r0
+       assertreg0 11
+       SEND    r1, 0, 12
+       ldbank  @r1, r0
+       assertreg0 12
+       SEND    r1, 0, 13
+       ldbank  @r1, r0
+       assertreg0 13
+       SEND    r1, 0, 14
+       ldbank  @r1, r0
+       assertreg0 14
+       SEND    r1, 0, 15
+       ldbank  @r1, r0
+       assertreg0 15
+       SEND    r1, 0, 16
+       ldbank  @r1, r0
+       assertreg0 16
+       SEND    r1, 0, 17
+       ldbank  @r1, r0
+       assertreg0 17
+       SEND    r1, 0, 18
+       ldbank  @r1, r0
+       assertreg0 18
+       SEND    r1, 0, 19
+       ldbank  @r1, r0
+       assertreg0 19
+
+       assertreg (19 << 2), r1
+       test_gr_a5a5 r2
+       test_gr_a5a5 r3
+       test_gr_a5a5 r4
+       test_gr_a5a5 r5
+       test_gr_a5a5 r6
+       test_gr_a5a5 r7
+       test_gr_a5a5 r8
+       test_gr_a5a5 r9
+       test_gr_a5a5 r10
+       test_gr_a5a5 r11
+       test_gr_a5a5 r12
+       test_gr_a5a5 r13
+       test_gr_a5a5 r14
+
+resbank_1:
+       set_grs_a5a5
+       mov     #1, r0
+       trapa   #13     ! magic trap, sets ibnr
+
+       resbank
+
+       assertreg0      0
+       assertreg       1, r1
+       assertreg       2, r2
+       assertreg       3, r3
+       assertreg       4, r4
+       assertreg       5, r5
+       assertreg       6, r6
+       assertreg       7, r7
+       assertreg       8, r8
+       assertreg       9, r9
+       assertreg       10, r10
+       assertreg       11, r11
+       assertreg       12, r12
+       assertreg       13, r13
+       assertreg       14, r14
+       assert_sreg     15, mach
+       assert_sreg     17, pr
+       assert_creg     18, gbr
+       assert_sreg     19, macl
+
+resbank_2:
+       set_grs_a5a5
+       movi20  #555, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+       add     #-1, r0
+       mov.l   r0, @-r15
+
+       set_sr_bit      (1 << 14)       ! set BO
+
+       resbank
+
+       assert_sreg     555, macl
+       assert_sreg     554, mach
+       assert_creg     553, gbr
+       assert_sreg     552, pr
+       assertreg       551, r14
+       assertreg       550, r13
+       assertreg       549, r12
+       assertreg       548, r11
+       assertreg       547, r10
+       assertreg       546, r9
+       assertreg       545, r8
+       assertreg       544, r7
+       assertreg       543, r6
+       assertreg       542, r5
+       assertreg       541, r4
+       assertreg       540, r3
+       assertreg       539, r2
+       assertreg       538, r1
+       assertreg0      537
+
+       mov             r15, r0
+       assertreg0      stackt
+
+       pass
+
+       exit 0