This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PRELIMINARY]: Patch to add bfd support for IBM s390


Hello Binutils folks, 

This is a patch that I received from IBM to add bfd support
for Linux running on their s390 mainframe.  It is a part of
their submission of gdb support for same.  Could you please
look it over, and suggest what you might need in addition
for acceptance (such as ChangeLogs)?  Addresses of our IBM
contacts are in the Cc: field.

Here's a list of the BFD files from the patch below.
I assume that those with "s390" in the filename can go
in without too much trouble (pending releases and 
changelog entries):

bfd/Makefile.am
bfd/Makefile.in
bfd/archures.c
bfd/bfd-in2.h
bfd/config.bfd
bfd/configure
bfd/configure.in
bfd/cpu-s390.c
bfd/elf32-s390.c
bfd/libbfd.h
bfd/targets.c
bfd-trad.-core.c

And here's the entire patch, including bits of opcodes, 
readline, include, and gdb.
diff -u -r --new-file gdb-5.0/bfd/Makefile.am gdb-5.0-s390/bfd/Makefile.am
--- gdb-5.0/bfd/Makefile.am	Sun Apr  9 14:17:37 2000
+++ gdb-5.0-s390/bfd/Makefile.am	Fri Aug 18 14:41:13 2000
@@ -66,6 +66,7 @@
 	cpu-pj.lo \
 	cpu-powerpc.lo \
 	cpu-rs6000.lo \
+	cpu-s390.lo \
 	cpu-sh.lo \
 	cpu-sparc.lo \
 	cpu-tic30.lo \
@@ -104,6 +105,7 @@
 	cpu-pj.c \
 	cpu-powerpc.c \
 	cpu-rs6000.c \
+	cpu-s390.c \
 	cpu-sh.c \
 	cpu-sparc.c \
 	cpu-tic30.c \
@@ -183,6 +185,7 @@
 	elf32-mips.lo \
 	elf32-pj.lo \
 	elf32-ppc.lo \
+	elf32-s390.lo \
 	elf32-sh.lo \
 	elf32-sparc.lo \
 	elf32-v850.lo \
@@ -314,6 +317,7 @@
 	elf32-mips.c \
 	elf32-pj.c \
 	elf32-ppc.c \
+	elf32-s390.c \
 	elf32-sh.c \
 	elf32-sparc.c \
 	elf32-v850.c \
@@ -718,6 +722,7 @@
 cpu-pj.lo: cpu-pj.c
 cpu-powerpc.lo: cpu-powerpc.c
 cpu-rs6000.lo: cpu-rs6000.c
+cpu-s390.lo: cpu-s390.c 
 cpu-sh.lo: cpu-sh.c
 cpu-sparc.lo: cpu-sparc.c
 cpu-tic30.lo: cpu-tic30.c
@@ -918,6 +923,9 @@
 elf32-ppc.lo: elf32-ppc.c $(INCDIR)/bfdlink.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
   $(INCDIR)/elf/ppc.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-s390.lo: elf32-s390.c $(INCDIR)/bfdlink.h elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+    elf32-target.h
 elf32-sh.lo: elf32-sh.c $(INCDIR)/bfdlink.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
   $(INCDIR)/elf/sh.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
diff -u -r --new-file gdb-5.0/bfd/Makefile.in gdb-5.0-s390/bfd/Makefile.in
--- gdb-5.0/bfd/Makefile.in	Sun Apr  9 14:17:37 2000
+++ gdb-5.0-s390/bfd/Makefile.in	Tue Jul 18 19:16:43 2000
@@ -181,6 +181,7 @@
 	cpu-pj.lo \
 	cpu-powerpc.lo \
 	cpu-rs6000.lo \
+	cpu-s390.lo \
 	cpu-sh.lo \
 	cpu-sparc.lo \
 	cpu-tic30.lo \
@@ -220,6 +221,7 @@
 	cpu-pj.c \
 	cpu-powerpc.c \
 	cpu-rs6000.c \
+	cpu-s390.c \
 	cpu-sh.c \
 	cpu-sparc.c \
 	cpu-tic30.c \
@@ -300,6 +302,7 @@
 	elf32-mips.lo \
 	elf32-pj.lo \
 	elf32-ppc.lo \
+	elf32-s390.lo \
 	elf32-sh.lo \
 	elf32-sparc.lo \
 	elf32-v850.lo \
@@ -432,6 +435,7 @@
 	elf32-mips.c \
 	elf32-pj.c \
 	elf32-ppc.c \
+	elf32-s390.c \
 	elf32-sh.c \
 	elf32-sparc.c \
 	elf32-v850.c \
@@ -1233,6 +1237,7 @@
 cpu-hppa.lo: cpu-hppa.c
 cpu-i370.lo: cpu-i370.c
 cpu-i386.lo: cpu-i386.c
+cpu-s390.lo: cpu-s390.c
 cpu-i860.lo: cpu-i860.c
 cpu-i960.lo: cpu-i960.c
 cpu-m32r.lo: cpu-m32r.c
@@ -1408,6 +1413,9 @@
 elf32-i386.lo: elf32-i386.c $(INCDIR)/bfdlink.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
   $(INCDIR)/elf/i386.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
+elf32-s390.lo: elf32-s390.c $(INCDIR)/bfdlink.h elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  elf32-target.h
 elf32-i860.lo: elf32-i860.c elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
   elf32-target.h
diff -u -r --new-file gdb-5.0/bfd/archures.c gdb-5.0-s390/bfd/archures.c
--- gdb-5.0/bfd/archures.c	Fri Apr  7 19:06:57 2000
+++ gdb-5.0-s390/bfd/archures.c	Tue Jul 18 19:16:43 2000
@@ -276,6 +276,7 @@
 extern const bfd_arch_info_type bfd_ns32k_arch;
 extern const bfd_arch_info_type bfd_w65_arch;
 extern const bfd_arch_info_type bfd_v850_arch;
+extern const bfd_arch_info_type bfd_s390_arch;
 extern const bfd_arch_info_type bfd_fr30_arch;
 extern const bfd_arch_info_type bfd_mcore_arch;
 extern const bfd_arch_info_type bfd_avr_arch;
@@ -306,6 +307,7 @@
   &bfd_mn10300_arch,
   &bfd_powerpc_arch,
   &bfd_rs6000_arch,
+  &bfd_s390_arch,
   &bfd_sh_arch,
   &bfd_sparc_arch,
   &bfd_tic30_arch,
@@ -842,7 +844,9 @@
       arch = bfd_arch_sh;
       number = bfd_mach_sh4;
       break;
-
+    case 390:
+      arch = bfd_arch_s390;
+      break;
     default:  
       return false;
     }
diff -u -r --new-file gdb-5.0/bfd/bfd-in2.h gdb-5.0-s390/bfd/bfd-in2.h
--- gdb-5.0/bfd/bfd-in2.h	Wed Apr 19 08:32:31 2000
+++ gdb-5.0-s390/bfd/bfd-in2.h	Tue Jul 18 19:16:43 2000
@@ -658,7 +658,8 @@
   PARAMS ((bfd *, struct bfd_link_info *));
 extern boolean bfd_sparclinux_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
-
+extern boolean bfd_s390linux_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
 /* mmap hacks */
 
 struct _bfd_window_internal;
@@ -1420,6 +1421,7 @@
 #define bfd_mach_m32rx         'x'
   bfd_arch_mn10200,    /* Matsushita MN10200 */
   bfd_arch_mn10300,    /* Matsushita MN10300 */
+  bfd_arch_s390,       /* IBM s390 */
 #define bfd_mach_mn10300               300
 #define bfd_mach_am33          330
   bfd_arch_fr30,
@@ -2291,6 +2293,23 @@
 significant 8 bits of a 24 bit word are placed into the least
 significant 8 bits of the opcode. */
   BFD_RELOC_TIC30_LDP,
+
+/* additional s390/elf relocations */
+  BFD_RELOC_390_8,
+  BFD_RELOC_390_12,
+  BFD_RELOC_390_16,
+  BFD_RELOC_390_GOT12,
+  BFD_RELOC_390_GOT32,
+  BFD_RELOC_390_PLT32,
+  BFD_RELOC_390_COPY,
+  BFD_RELOC_390_GLOB_DAT,
+  BFD_RELOC_390_JMP_SLOT,
+  BFD_RELOC_390_RELATIVE,
+  BFD_RELOC_390_GOTOFF,
+  BFD_RELOC_390_GOTPC,
+  BFD_RELOC_390_GOT16,
+  BFD_RELOC_390_PC16DBL,
+  BFD_RELOC_390_PLT16DBL,
 
 /* This is a 7bit reloc for the tms320c54x, where the least
 significant 7 bits of a 16 bit word are placed into the least
diff -u -r --new-file gdb-5.0/bfd/config.bfd gdb-5.0-s390/bfd/config.bfd
--- gdb-5.0/bfd/config.bfd	Fri Apr  7 19:06:58 2000
+++ gdb-5.0-s390/bfd/config.bfd	Tue Jul 18 19:16:43 2000
@@ -43,6 +43,7 @@
 pj*)	targ_archs="bfd_pj_arch bfd_i386_arch";;
 powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
 rs6000)	targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
+s390*)  targ_archs=bfd_s390_arch;; 
 sparc*) targ_archs=bfd_sparc_arch ;;
 v850*)	targ_archs=bfd_v850_arch ;;
 z8k*)	targ_archs=bfd_z8k_arch ;;
@@ -383,7 +384,9 @@
     targ_defvec=bfd_elf32_i960_vec
     targ_selvecs="icoff_little_vec icoff_big_vec"
     ;;
-
+  s390-*-linux*)
+    targ_defvec=bfd_elf32_s390_vec
+    ;; 
   m32r-*-*)
     targ_defvec=bfd_elf32_m32r_vec
     ;;
diff -u -r --new-file gdb-5.0/bfd/configure gdb-5.0-s390/bfd/configure
--- gdb-5.0/bfd/configure	Sun Apr  9 14:17:37 2000
+++ gdb-5.0-s390/bfd/configure	Wed Jul 26 00:09:16 2000
@@ -4474,6 +4463,7 @@
   hppa*-*-mpeix*)	COREFILE=hpux-core.lo ;;
   hppa*-*-bsd*)		COREFILE="hpux-core.lo hppabsd-core.lo"
 			COREFLAG="-DHPUX_CORE -DHPPABSD_CORE" ;;
+  s390-*-*)             COREFILE=trad-core.lo ;;	
   i370-*-*)		
 	COREFILE=trad-core.lo
 	TRAD_HEADER='"hosts/i370linux.h"'
@@ -5133,6 +5123,7 @@
     bfd_elf64_littlemips_vec) 	tb="$tb elf64-mips.lo elf64.lo elf32-mips.lo elf32.lo $elf ecofflink.lo"
 				target64=true ;;
     bfd_elf32_m32r_vec)		tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+    bfd_elf32_s390_vec)         tb="$tb elf32-s390.lo elf32.lo $elf" ;;
     bfd_elf32_m68k_vec)		tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
     bfd_elf32_m88k_vec)		tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
     bfd_elf32_mcore_big_vec)	tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
diff -u -r --new-file gdb-5.0/bfd/configure.in gdb-5.0-s390/bfd/configure.in
--- gdb-5.0/bfd/configure.in	Sun Apr  9 14:17:38 2000
+++ gdb-5.0-s390/bfd/configure.in	Wed Jul 26 00:09:16 2000
@@ -147,6 +147,7 @@
   hppa*-*-mpeix*)	COREFILE=hpux-core.lo ;;
   hppa*-*-bsd*)		COREFILE="hpux-core.lo hppabsd-core.lo"
 			COREFLAG="-DHPUX_CORE -DHPPABSD_CORE" ;;
+  s390-*-*)             COREFILE=trad-core.lo ;;	
   i370-*-*)		
 	COREFILE=trad-core.lo
 	TRAD_HEADER='"hosts/i370linux.h"'
@@ -490,6 +491,7 @@
     bfd_elf64_littlemips_vec) 	tb="$tb elf64-mips.lo elf64.lo elf32-mips.lo elf32.lo $elf ecofflink.lo"
 				target64=true ;;
     bfd_elf32_m32r_vec)		tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+    bfd_elf32_s390_vec)         tb="$tb elf32-s390.lo elf32.lo $elf" ;;
     bfd_elf32_m68k_vec)		tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
     bfd_elf32_m88k_vec)		tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
     bfd_elf32_mcore_big_vec)	tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
diff -u -r --new-file gdb-5.0/bfd/cpu-s390.c gdb-5.0-s390/bfd/cpu-s390.c
--- gdb-5.0/bfd/cpu-s390.c	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/bfd/cpu-s390.c	Tue Jul 18 19:16:44 2000
@@ -0,0 +1,40 @@
+/* BFD support for the s390 processor.
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+   Contributed by Carl B. Pedersen and Martin Schwidefsky.
+
+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_s390_arch =
+{
+    32,	/* bits in a word */
+    32,	/* bits in an address */
+    8,	/* bits in a byte */
+    bfd_arch_s390,
+    0,  /* only one machine */
+    "s390",
+    "s390:390",
+    3, /* section alignment power */
+    true, /* the default */
+    bfd_default_compatible,
+    bfd_default_scan,
+    NULL
+};
diff -u -r --new-file gdb-5.0/bfd/elf32-s390.c gdb-5.0-s390/bfd/elf32-s390.c
--- gdb-5.0/bfd/elf32-s390.c	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/bfd/elf32-s390.c	Tue Jul 18 19:16:44 2000
@@ -0,0 +1,2001 @@
+/* IBM S/390-specific support for 32-bit ELF
+   Copyright (C) 1999,2000 Free Software Foundation, Inc.
+   Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+   Contributed by Carl B. Pedersen and Martin Schwidefsky.
+
+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.  */
+
+/* September 1998
+   Source file for the IBM 390 made from elf32-sparc.c and elf32-i386.c
+
+   Relocation type Elf32_Rela used.
+*/
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/s390.h"
+
+#define USE_RELA 1		/* we want RELA relocations, not REL */
+
+static reloc_howto_type *elf32_s390_reloc_type_lookup
+  PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void elf32_s390_info_to_howto
+  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+static boolean elf_s390_is_local_label_name PARAMS ((bfd *, const char *));
+static struct bfd_hash_entry *elf_s390_link_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+static struct bfd_link_hash_table *elf_s390_link_hash_table_create
+  PARAMS ((bfd *));
+static boolean elf32_s390_check_relocs
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+	   const Elf_Internal_Rela *));
+static boolean elf32_s390_adjust_dynamic_symbol
+  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static boolean elf32_s390_size_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf32_s390_relocate_section
+  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static boolean elf32_s390_finish_dynamic_symbol
+  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+	   Elf_Internal_Sym *));
+static boolean elf32_s390_finish_dynamic_sections
+  PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf32_s390_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+
+/* The relocation "howto" table.  */
+
+static bfd_reloc_status_type s390_elf_notsupported_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+reloc_howto_type _bfd_s390_elf_howto_table[] =
+{
+  HOWTO (R_390_NONE,		/* type */
+	 0,			/* rightshift */
+	 0,			/* size (0 = byte, 1 = short, 2 = long) */
+	 0,			/* bitsize */
+	 false,			/* pc_relative */
+	 0,			/* bitpos */
+	 complain_overflow_dont, /* complain_on_overflow */
+	 bfd_elf_generic_reloc, /* special_function */
+	 "R_390_NONE",		/* name */
+	 false,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0,			/* dst_mask */
+	 false),		/* pcrel_offset */
+
+  HOWTO(R_390_8,         0, 0,  8, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_8",       false, 0,0x000000ff, false),
+  HOWTO(R_390_12,        0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_12",      false, 0,0x00000fff, false),
+  HOWTO(R_390_16,        0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_16",      false, 0,0x0000ffff, false),
+  HOWTO(R_390_32,        0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_32",      false, 0,0xffffffff, false),
+  HOWTO(R_390_PC32,	 0, 2, 32,  true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32",    false, 0,0xffffffff,  true),
+  HOWTO(R_390_GOT12,	 0, 1, 12, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT12",   false, 0,0x00000fff, false),
+  HOWTO(R_390_GOT32,	 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT32",   false, 0,0xffffffff, false),
+  HOWTO(R_390_PLT32,	 0, 2, 32,  true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32",   false, 0,0xffffffff,  true),
+  HOWTO(R_390_COPY,      0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_COPY",    false, 0,0xffffffff, false),
+  HOWTO(R_390_GLOB_DAT,  0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GLOB_DAT",false, 0,0xffffffff, false),
+  HOWTO(R_390_JMP_SLOT,  0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_JMP_SLOT",false, 0,0xffffffff, false),
+  HOWTO(R_390_RELATIVE,  0, 2, 32,  true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_RELATIVE",false, 0,0xffffffff, false),
+  HOWTO(R_390_GOTOFF,    0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTOFF",  false, 0,0xffffffff, false),
+  HOWTO(R_390_GOTPC,     0, 2, 32,  true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPC",   false, 0,0xffffffff,  true),
+  HOWTO(R_390_GOT16,     0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT16",   false, 0,0x0000ffff, false),
+  HOWTO(R_390_PC16,      0, 1, 16,  true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16",    false, 0,0x0000ffff,  true),
+  HOWTO(R_390_PC16DBL,   1, 1, 16,  true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16DBL", false, 0,0x0000ffff,  true),
+  HOWTO(R_390_PLT16DBL,  1, 1, 16,  true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT16DBL", false, 0,0x0000ffff,  true),
+};
+
+static reloc_howto_type *
+elf32_s390_reloc_type_lookup (abfd, code)
+     bfd *abfd;
+     bfd_reloc_code_real_type code;
+{
+  switch (code) {
+  case BFD_RELOC_NONE:
+    return &_bfd_s390_elf_howto_table[(int) R_390_NONE];
+  case BFD_RELOC_8:
+    return &_bfd_s390_elf_howto_table[(int) R_390_8];
+  case BFD_RELOC_390_12:
+    return &_bfd_s390_elf_howto_table[(int) R_390_12];
+  case BFD_RELOC_16:
+    return &_bfd_s390_elf_howto_table[(int) R_390_16];
+  case BFD_RELOC_32:
+    return &_bfd_s390_elf_howto_table[(int) R_390_32];
+  case BFD_RELOC_32_PCREL:
+    return &_bfd_s390_elf_howto_table[(int) R_390_PC32];
+  case BFD_RELOC_390_GOT12:
+    return &_bfd_s390_elf_howto_table[(int) R_390_GOT12];
+  case BFD_RELOC_390_GOT32:
+    return &_bfd_s390_elf_howto_table[(int) R_390_GOT32];
+  case BFD_RELOC_390_PLT32:
+    return &_bfd_s390_elf_howto_table[(int) R_390_PLT32];
+  case BFD_RELOC_390_COPY:
+    return &_bfd_s390_elf_howto_table[(int) R_390_COPY];
+  case BFD_RELOC_390_GLOB_DAT:
+    return &_bfd_s390_elf_howto_table[(int) R_390_GLOB_DAT];
+  case BFD_RELOC_390_JMP_SLOT:
+    return &_bfd_s390_elf_howto_table[(int) R_390_JMP_SLOT];
+  case BFD_RELOC_390_RELATIVE:
+    return &_bfd_s390_elf_howto_table[(int) R_390_RELATIVE];
+  case BFD_RELOC_390_GOTOFF:
+    return &_bfd_s390_elf_howto_table[(int) R_390_GOTOFF];
+  case BFD_RELOC_390_GOTPC:
+    return &_bfd_s390_elf_howto_table[(int) R_390_GOTPC];
+  case BFD_RELOC_390_GOT16:
+    return &_bfd_s390_elf_howto_table[(int) R_390_GOT16];
+  case BFD_RELOC_16_PCREL:
+    return &_bfd_s390_elf_howto_table[(int) R_390_PC16];
+  case BFD_RELOC_390_PC16DBL:
+    return &_bfd_s390_elf_howto_table[(int) R_390_PC16DBL];
+  case BFD_RELOC_390_PLT16DBL:
+    return &_bfd_s390_elf_howto_table[(int) R_390_PLT16DBL];
+  }
+  return 0;
+}
+
+/* We need to use ELF32_R_TYPE so we have our own copy of this function,
+   and elf32-s390.c has its own copy.  */
+
+static void
+elf32_s390_info_to_howto (abfd, cache_ptr, dst)
+     bfd *abfd;
+     arelent *cache_ptr;
+     Elf_Internal_Rela *dst;
+{
+  BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_390_max);
+  cache_ptr->howto = &_bfd_s390_elf_howto_table[ELF32_R_TYPE(dst->r_info)];
+}
+
+/* For unsupported relocs.  */
+
+static bfd_reloc_status_type
+s390_elf_notsupported_reloc (abfd,
+			     reloc_entry,
+			     symbol,
+			     data,
+			     input_section,
+			     output_bfd,
+			     error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     asymbol *symbol;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message;
+{
+  return bfd_reloc_notsupported;
+}
+
+
+
+static boolean
+elf_s390_is_local_label_name (abfd, name)
+     bfd *abfd;
+     const char *name;
+{
+  if (name[0] == '.' && name[1] == 'X')
+    return true;
+
+  return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* Functions for the 390 ELF linker.  */
+
+/* The name of the dynamic interpreter.  This is put in the .interp
+   section.  */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+/* The nop opcode we use.  */
+
+#define s390_NOP 0x07070707
+
+
+/* The size in bytes of the first entry in the procedure linkage table.  */
+#define PLT_FIRST_ENTRY_SIZE 32
+/* The size in bytes of an entry in the procedure linkage table.  */
+#define PLT_ENTRY_SIZE 32 
+
+#define GOT_ENTRY_SIZE 4
+
+/* The first three entries in a procedure linkage table are reserved,
+   and the initial contents are unimportant (we zero them out).
+   Subsequent entries look like this.  See the SVR4 ABI 386
+   supplement to see how this works.  */
+
+/* For the s390, simple addr offset can only be 0 - 4096.
+   To use the full 2 GB address space, several instructions
+   are needed to load an address in a register and execute
+   a branch( or just saving the address)
+
+   Furthermore, only r 0 and 1 are free to use!!!
+
+*/ 
+
+/* 
+   The first 3 words in the GOT are then reserved.
+   Word 0 is the address of the dynamic table.
+   Word 1 is a pointer to a structure describing the object
+   Word 2 is used to point to the loader entry address.
+
+   The code for position independand PLT entries looks like this:
+
+   r12 holds addr of the current GOT at entry to the PLT
+
+   The GOT holds the address in the PLT to be executed.
+   The loader then gets:
+   24(15) =  Pointer to the structure describing the object.
+   28(15) =  Offset in symbol table                                             
+
+   The loader  must  then find the module where the function is
+   and insert the address in the GOT.
+
+  Note: 390 can only address +- 64 K relative.
+        We check if offset > 65536, then make a relative branch -64xxx
+        back to a previous defined branch
+
+
+PLT1: BASR 1,0         # 2 bytes
+      L    1,22(1)     # 4 bytes  Load offset in GOT in r 1
+      L    1,(1,12)    # 4 bytes  Load address from GOT in r1
+      BCR  15,1        # 2 bytes  Jump to address
+RET1: BASR 1,0         # 2 bytes  Return from GOT 1st time
+      L    1,14(1)     # 4 bytes  Load offset in symol table in r1
+      BRC  15,-x       # 4 bytes  Jump to start of PLT
+      .word 0          # 2 bytes filler
+      .long ?          # 4 bytes  offset in GOT
+      .long ?          # 4 bytes  offset into symbol table
+
+Total = 32 bytes per PLT entry
+
+   The code for static build PLT entries looks like this:
+
+PLT1: BASR 1,0         # 2 bytes
+      L    1,22(1)     # 4 bytes  Load address of GOT entry
+      L    1,0(0,1)    # 4 bytes  Load address from GOT in r1
+      BCR  15,1        # 2 bytes  Jump to address
+RET1: BASR 1,0         # 2 bytes  Return from GOT 1st time
+      L    1,14(1)     # 4 bytes  Load offset in symbol table in r1
+      BRC  15,-x       # 4 bytes  Jump to start of PLT
+      .word 0          # 2 bytes  filler
+      .long ?          # 4 bytes  address of GOT entry
+      .long ?          # 4 bytes  offset into symbol table
+*/
+
+#define PLT_PIC_ENTRY_WORD0 0x0d105810
+#define PLT_PIC_ENTRY_WORD1 0x10165811
+#define PLT_PIC_ENTRY_WORD2 0xc00007f1
+#define PLT_PIC_ENTRY_WORD3 0x0d105810
+#define PLT_PIC_ENTRY_WORD4 0x100ea7f4
+
+#define PLT_ENTRY_WORD0     0x0d105810
+#define PLT_ENTRY_WORD1     0x10165810
+#define PLT_ENTRY_WORD2     0x100007f1
+#define PLT_ENTRY_WORD3     0x0d105810
+#define PLT_ENTRY_WORD4     0x100ea7f4
+
+/*
+   The first PLT entry pushes the offset into the symbol table
+   from R1 onto the stack at 8(15) and the loader object info
+   at 12(15), loads the loader address in R1 and jumps to it. 
+*/
+
+/* The first entry in the PLT for PIC code:
+
+PLT0:
+   ST   1,28(15)  # R1 has offset into symbol table
+   L    1,4(12)   # Get loader ino(object struct address)
+   ST   1,24(15)  # Store address 
+   L    1,8(12)   # Entry address of loader in R1
+   BR   1         # Jump to loader
+
+   The first entry in the PLT for static code:
+
+PLT0:
+   ST   1,28(15)      # R1 has offset into symbol table
+   BASR 1,0
+   L    1,18(0,1)     # Get address of GOT
+   MVC  24(4,15),4(1) # Move loader ino to stack
+   L    1,8(1)        # Get address of loader
+   BR   1             # Jump to loader
+   .word 0            # filler
+   .long got          # address of GOT
+*/
+
+#define PLT_PIC_FIRST_ENTRY_WORD0 0x5010f01c
+#define PLT_PIC_FIRST_ENTRY_WORD1 0x5810c004
+#define PLT_PIC_FIRST_ENTRY_WORD2 0x5010f018
+#define PLT_PIC_FIRST_ENTRY_WORD3 0x5810c008
+#define PLT_PIC_FIRST_ENTRY_WORD4 0x07f10000
+
+#define PLT_FIRST_ENTRY_WORD0     0x5010f01c
+#define PLT_FIRST_ENTRY_WORD1     0x0d105810
+#define PLT_FIRST_ENTRY_WORD2     0x1012D203
+#define PLT_FIRST_ENTRY_WORD3     0xf0181004
+#define PLT_FIRST_ENTRY_WORD4     0x58101008
+#define PLT_FIRST_ENTRY_WORD5     0x07f10000
+
+/* The s390 linker needs to keep track of the number of relocs that it
+   decides to copy in check_relocs for each symbol.  This is so that
+   it can discard PC relative relocs if it doesn't need them when
+   linking with -Bsymbolic.  We store the information in a field
+   extending the regular ELF linker hash table.  */
+
+/* This structure keeps track of the number of PC relative relocs we
+   have copied for a given symbol.  */
+
+struct elf_s390_pcrel_relocs_copied
+{
+  /* Next section.  */
+  struct elf_s390_pcrel_relocs_copied *next;
+  /* A section in dynobj.  */
+  asection *section;
+  /* Number of relocs copied in this section.  */
+  bfd_size_type count;
+};
+
+/* s390 ELF linker hash entry.  */
+
+struct elf_s390_link_hash_entry
+{
+  struct elf_link_hash_entry root;
+
+  /* Number of PC relative relocs copied for this symbol.  */
+  struct elf_s390_pcrel_relocs_copied *pcrel_relocs_copied;
+};
+
+/* s390 ELF linker hash table.  */
+
+struct elf_s390_link_hash_table
+{
+  struct elf_link_hash_table root;
+};
+
+/* Declare this now that the above structures are defined.  */
+
+static boolean elf_s390_discard_copies
+  PARAMS ((struct elf_s390_link_hash_entry *, PTR));
+
+/* Traverse an s390 ELF linker hash table.  */
+
+#define elf_s390_link_hash_traverse(table, func, info)			\
+  (elf_link_hash_traverse						\
+   (&(table)->root,							\
+    (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func),	\
+    (info)))
+
+/* Get the s390 ELF linker hash table from a link_info structure.  */
+
+#define elf_s390_hash_table(p) \
+  ((struct elf_s390_link_hash_table *) ((p)->hash))
+
+/* Create an entry in an s390 ELF linker hash table.  */
+
+static struct bfd_hash_entry *
+elf_s390_link_hash_newfunc (entry, table, string)
+     struct bfd_hash_entry *entry;
+     struct bfd_hash_table *table;
+     const char *string;
+{
+  struct elf_s390_link_hash_entry *ret =
+    (struct elf_s390_link_hash_entry *) entry;
+
+  /* Allocate the structure if it has not already been allocated by a
+     subclass.  */
+  if (ret == (struct elf_s390_link_hash_entry *) NULL)
+    ret = ((struct elf_s390_link_hash_entry *)
+	   bfd_hash_allocate (table,
+			      sizeof (struct elf_s390_link_hash_entry)));
+  if (ret == (struct elf_s390_link_hash_entry *) NULL)
+    return (struct bfd_hash_entry *) ret;
+
+  /* Call the allocation method of the superclass.  */
+  ret = ((struct elf_s390_link_hash_entry *)
+	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+				     table, string));
+  if (ret != (struct elf_s390_link_hash_entry *) NULL)
+    {
+      ret->pcrel_relocs_copied = NULL;
+    }
+
+  return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an s390 ELF linker hash table.  */
+
+static struct bfd_link_hash_table *
+elf_s390_link_hash_table_create (abfd)
+     bfd *abfd;
+{
+  struct elf_s390_link_hash_table *ret;
+
+  ret = ((struct elf_s390_link_hash_table *)
+	 bfd_alloc (abfd, sizeof (struct elf_s390_link_hash_table)));
+  if (ret == (struct elf_s390_link_hash_table *) NULL)
+    return NULL;
+
+  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
+				       elf_s390_link_hash_newfunc))
+    {
+      bfd_release (abfd, ret);
+      return NULL;
+    }
+
+  return &ret->root.root;
+}
+
+
+/* Look through the relocs for a section during the first phase, and
+   allocate space in the global offset table or procedure linkage
+   table.  */
+
+static boolean
+elf32_s390_check_relocs (abfd, info, sec, relocs)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     asection *sec;
+     const Elf_Internal_Rela *relocs;
+{
+  bfd *dynobj;
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  bfd_vma *local_got_offsets;
+  const Elf_Internal_Rela *rel;
+  const Elf_Internal_Rela *rel_end;
+  asection *sgot;
+  asection *srelgot;
+  asection *sreloc;
+
+  if (info->relocateable)
+    return true;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  local_got_offsets = elf_local_got_offsets (abfd);
+
+  sgot = NULL;
+  srelgot = NULL;
+  sreloc = NULL;
+
+  rel_end = relocs + sec->reloc_count;
+  for (rel = relocs; rel < rel_end; rel++)
+    {
+      unsigned long r_symndx;
+      struct elf_link_hash_entry *h;
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      if (r_symndx < symtab_hdr->sh_info)
+	h = NULL;
+      else
+	h = sym_hashes[r_symndx - symtab_hdr->sh_info];      
+
+      /* Some relocs require a global offset table.  */
+      if (dynobj == NULL)
+	{
+	  switch (ELF32_R_TYPE (rel->r_info))
+	    {
+	    case R_390_GOT12:
+            case R_390_GOT16:
+	    case R_390_GOT32:
+	    case R_390_GOTOFF:
+	    case R_390_GOTPC:
+	      elf_hash_table (info)->dynobj = dynobj = abfd;
+	      if (! _bfd_elf_create_got_section (dynobj, info))
+		return false;
+	      break;
+
+	    default:
+	      break;
+	    }
+	}
+
+
+      switch (ELF32_R_TYPE (rel->r_info))
+	{
+	case R_390_GOT12:
+        case R_390_GOT16:
+	case R_390_GOT32:
+	  /* This symbol requires a global offset table entry.  */
+
+	  if (sgot == NULL)
+	    {
+	      sgot = bfd_get_section_by_name (dynobj, ".got");
+	      BFD_ASSERT (sgot != NULL);
+	    }
+
+
+	  if (srelgot == NULL
+	      && (h != NULL || info->shared))
+	    {
+	      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+	      if (srelgot == NULL)
+		{
+		  srelgot = bfd_make_section (dynobj, ".rela.got");
+		  if (srelgot == NULL
+		      || ! bfd_set_section_flags (dynobj, srelgot,
+						  (SEC_ALLOC
+						   | SEC_LOAD
+						   | SEC_HAS_CONTENTS
+						   | SEC_IN_MEMORY
+						   | SEC_LINKER_CREATED
+						   | SEC_READONLY))
+		      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+		    return false;
+		}
+	    }
+
+	  if (h != NULL)
+	    {
+	      if (h->got.offset != (bfd_vma) -1)
+		{
+		  /* We have already allocated space in the .got.  */
+		  break;
+		}
+	      h->got.offset = sgot->_raw_size;
+
+	      /* Make sure this symbol is output as a dynamic symbol.  */
+	      if (h->dynindx == -1)
+		{
+		  if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+		    return false;
+		}
+
+	      srelgot->_raw_size += sizeof (Elf32_External_Rela);
+	    }
+	  else
+	    {
+     	      /* This is a global offset table entry for a local
+                 symbol.  */
+	      if (local_got_offsets == NULL)
+		{
+		  size_t size;
+		  register unsigned int i;
+
+		  size = symtab_hdr->sh_info * sizeof (bfd_vma);
+		  local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+		  if (local_got_offsets == NULL)
+		    return false;
+		  elf_local_got_offsets (abfd) = local_got_offsets;
+		  for (i = 0; i < symtab_hdr->sh_info; i++)
+		    local_got_offsets[i] = (bfd_vma) -1;
+		}
+	      if (local_got_offsets[r_symndx] != (bfd_vma) -1)
+		{
+		  /* We have already allocated space in the .got.  */
+		  break;
+		}
+	      local_got_offsets[r_symndx] = sgot->_raw_size;
+
+	      if (info->shared)
+		{
+		  /* If we are generating a shared object, we need to
+                     output a R_390_RELATIVE reloc so that the dynamic
+                     linker can adjust this GOT entry.  */
+		  srelgot->_raw_size += sizeof (Elf32_External_Rela);
+		}
+	    }
+
+	  sgot->_raw_size += GOT_ENTRY_SIZE;
+
+	  break;
+
+        case R_390_PLT16DBL:
+	case R_390_PLT32:
+	  /* This symbol requires a procedure linkage table entry.  We
+             actually build the entry in adjust_dynamic_symbol,
+             because this might be a case of linking PIC code which is
+             never referenced by a dynamic object, in which case we
+             don't need to generate a procedure linkage table entry
+             after all.  
+           */
+
+	  /* If this is a local symbol, we resolve it directly without
+             creating a procedure linkage table entry.  */
+	  if (h == NULL)
+	    continue;
+
+	  h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+
+	  break;
+
+        case R_390_8:
+        case R_390_16:
+	case R_390_32:
+        case R_390_PC16:
+        case R_390_PC16DBL:
+	case R_390_PC32:
+	  /* If we are creating a shared library, and this is a reloc
+             against a global symbol, or a non PC relative reloc
+             against a local symbol, then we need to copy the reloc
+             into the shared library.  However, if we are linking with
+             -Bsymbolic, we do not need to copy a reloc against a
+             global symbol which is defined in an object we are
+             including in the link (i.e., DEF_REGULAR is set).  At
+             this point we have not seen all the input files, so it is
+             possible that DEF_REGULAR is not set now but will be set
+             later (it is never cleared).  We account for that
+             possibility below by storing information in the
+             pcrel_relocs_copied field of the hash table entry.  */
+	  if (info->shared
+	      && ((ELF32_R_TYPE (rel->r_info) != R_390_PC16 &&
+                   ELF32_R_TYPE (rel->r_info) != R_390_PC16DBL &&
+                   ELF32_R_TYPE (rel->r_info) != R_390_PC32)
+		  || (h != NULL
+		      && (! info->symbolic
+			  || (h->elf_link_hash_flags
+			      & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+	    {
+	      /* When creating a shared object, we must copy these
+                 reloc types into the output file.  We create a reloc
+                 section in dynobj and make room for this reloc.  */
+	      if (sreloc == NULL)
+		{
+		  const char *name;
+
+		  name = (bfd_elf_string_from_elf_section
+			  (abfd,
+			   elf_elfheader (abfd)->e_shstrndx,
+			   elf_section_data (sec)->rel_hdr.sh_name));
+		  if (name == NULL)
+		    return false;
+
+		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+			      && strcmp (bfd_get_section_name (abfd, sec),
+					 name + 5) == 0);
+
+		  sreloc = bfd_get_section_by_name (dynobj, name);
+		  if (sreloc == NULL)
+		    {
+		      flagword flags;
+
+		      sreloc = bfd_make_section (dynobj, name);
+		      flags = (SEC_HAS_CONTENTS | SEC_READONLY
+			       | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+		      if ((sec->flags & SEC_ALLOC) != 0)
+			flags |= SEC_ALLOC | SEC_LOAD;
+		      if (sreloc == NULL
+			  || ! bfd_set_section_flags (dynobj, sreloc, flags)
+			  || ! bfd_set_section_alignment (dynobj, sreloc, 2))
+			return false;
+		    }
+		}
+
+	      sreloc->_raw_size += sizeof (Elf32_External_Rela);
+
+	      /* If we are linking with -Bsymbolic, and this is a
+                 global symbol, we count the number of PC relative
+                 relocations we have entered for this symbol, so that
+                 we can discard them again if the symbol is later
+                 defined by a regular object.  Note that this function
+                 is only called if we are using an elf_s390 linker
+                 hash table, which means that h is really a pointer to
+                 an elf_s390_link_hash_entry.  */
+	      if (h != NULL && info->symbolic
+		  && (ELF32_R_TYPE (rel->r_info) == R_390_PC16 ||
+                      ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL ||
+                      ELF32_R_TYPE (rel->r_info) == R_390_PC32))
+		{
+		  struct elf_s390_link_hash_entry *eh;
+		  struct elf_s390_pcrel_relocs_copied *p;
+
+		  eh = (struct elf_s390_link_hash_entry *) h;
+
+		  for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
+		    if (p->section == sreloc)
+		      break;
+
+		  if (p == NULL)
+		    {
+		      p = ((struct elf_s390_pcrel_relocs_copied *)
+			   bfd_alloc (dynobj, sizeof *p));
+		      if (p == NULL)
+			return false;
+		      p->next = eh->pcrel_relocs_copied;
+		      eh->pcrel_relocs_copied = p;
+		      p->section = sreloc;
+		      p->count = 0;
+		    }
+
+		  ++p->count;
+		}
+	    }
+
+	  break;
+
+	default:
+	  break;
+	}
+    }
+
+  return true;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+   regular object.  The current definition is in some section of the
+   dynamic object, but we're not including those sections.  We have to
+   change the definition to something the rest of the link can
+   understand.  */
+
+static boolean
+elf32_s390_adjust_dynamic_symbol (info, h)
+     struct bfd_link_info *info;
+     struct elf_link_hash_entry *h;
+{
+  bfd *dynobj;
+  asection *s;
+  unsigned int power_of_two;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  /* Make sure we know what is going on here.  */
+  BFD_ASSERT (dynobj != NULL
+	      && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
+		  || h->weakdef != NULL
+		  || ((h->elf_link_hash_flags
+		       & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+		      && (h->elf_link_hash_flags
+			  & ELF_LINK_HASH_REF_REGULAR) != 0
+		      && (h->elf_link_hash_flags
+			  & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+
+  /* If this is a function, put it in the procedure linkage table.  We
+     will fill in the contents of the procedure linkage table later
+     (although we could actually do it here). */
+  if (h->type == STT_FUNC
+      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+    {
+      if (! info->shared
+	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+	  && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+	{
+	  /* This case can occur if we saw a PLT32 reloc in an input
+             file, but the symbol was never referred to by a dynamic
+             object.  In such a case, we don't actually need to build
+             a procedure linkage table, and we can just do a PC32
+             reloc instead.  */
+	  BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+	  return true;
+	}
+
+      /* Make sure this symbol is output as a dynamic symbol.  */
+      if (h->dynindx == -1)
+	{
+	  if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+	    return false;
+	}
+
+      s = bfd_get_section_by_name (dynobj, ".plt");
+      BFD_ASSERT (s != NULL);
+
+
+      /* The first  entry in .plt is reserved.  */
+      if (s->_raw_size == 0)
+	s->_raw_size = PLT_FIRST_ENTRY_SIZE;
+
+     /* If this symbol is not defined in a regular file, and we are
+       not generating a shared library, then set the symbol to this
+       location in the .plt.  This is required to make function
+       pointers compare as equal between the normal executable and
+       the shared library.  */
+     if (! info->shared
+	&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+      {
+	h->root.u.def.section = s;
+	h->root.u.def.value = s->_raw_size;
+      }
+
+      h->plt.offset = s->_raw_size;
+
+      /* Make room for this entry.  */
+      s->_raw_size += PLT_ENTRY_SIZE;
+
+      /* We also need to make an entry in the .got.plt section, which
+	 will be placed in the .got section by the linker script.  */
+
+      s = bfd_get_section_by_name (dynobj, ".got.plt");
+      BFD_ASSERT (s != NULL);
+      s->_raw_size += GOT_ENTRY_SIZE;
+
+      /* We also need to make an entry in the .rela.plt section.  */
+
+      s = bfd_get_section_by_name (dynobj, ".rela.plt");
+      BFD_ASSERT (s != NULL);
+      s->_raw_size += sizeof (Elf32_External_Rela);
+
+      return true;
+    }
+
+  /* If this is a weak symbol, and there is a real definition, the
+     processor independent code will have arranged for us to see the
+     real definition first, and we can just use the same value.  */
+  if (h->weakdef != NULL)
+    {
+      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
+		  || h->weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->weakdef->root.u.def.section;
+      h->root.u.def.value = h->weakdef->root.u.def.value;
+      return true;
+    }
+
+  /* This is a reference to a symbol defined by a dynamic object which
+     is not a function.  */
+
+  /* If we are creating a shared library, we must presume that the
+     only references to the symbol are via the global offset table.
+     For such cases we need not do anything here; the relocations will
+     be handled correctly by relocate_section.  */
+  if (info->shared)
+    return true;
+
+  /* We must allocate the symbol in our .dynbss section, which will
+     become part of the .bss section of the executable.  There will be
+     an entry for this symbol in the .dynsym section.  The dynamic
+     object will contain position independent code, so all references
+     from the dynamic object to this symbol will go through the global
+     offset table.  The dynamic linker will use the .dynsym entry to
+     determine the address it must put in the global offset table, so
+     both the dynamic object and the regular object will refer to the
+     same memory location for the variable.  */
+
+  s = bfd_get_section_by_name (dynobj, ".dynbss");
+  BFD_ASSERT (s != NULL);
+
+  /* We must generate a R_390_COPY reloc to tell the dynamic linker
+     to copy the initial value out of the dynamic object and into the
+     runtime process image.  We need to remember the offset into the
+     .rel.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+    {
+      asection *srel;
+
+      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+      BFD_ASSERT (srel != NULL);
+      srel->_raw_size += sizeof (Elf32_External_Rela);
+      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
+    }
+
+  /* We need to figure out the alignment required for this symbol.  I
+     have no idea how ELF linkers handle this.  */
+  power_of_two = bfd_log2 (h->size);
+  if (power_of_two > 3)
+    power_of_two = 3;
+
+  /* Apply the required alignment.  */
+  s->_raw_size = BFD_ALIGN (s->_raw_size,
+			    (bfd_size_type) (1 << power_of_two));
+  if (power_of_two > bfd_get_section_alignment (dynobj, s))
+    {
+      if (! bfd_set_section_alignment (dynobj, s, power_of_two))
+	return false;
+    }
+
+  /* Define the symbol as being at this point in the section.  */
+  h->root.u.def.section = s;
+  h->root.u.def.value = s->_raw_size;
+
+  /* Increment the section size to make room for the symbol.  */
+  s->_raw_size += h->size;
+
+  return true;
+}
+
+/* Set the sizes of the dynamic sections.  */
+
+static boolean
+elf32_s390_size_dynamic_sections (output_bfd, info)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+{
+  bfd *dynobj;
+  asection *s;
+  boolean reltext;
+  boolean relocs;
+  boolean plt;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  BFD_ASSERT (dynobj != NULL);
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      /* Set the contents of the .interp section to the interpreter.  */
+      if (! info->shared)
+	{
+	  s = bfd_get_section_by_name (dynobj, ".interp");
+	  BFD_ASSERT (s != NULL);
+	  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+	}
+    }
+  else
+    {
+      /* We may have created entries in the .rela.got section.
+         However, if we are not creating the dynamic sections, we will
+         not actually use these entries.  Reset the size of .rela.got,
+         which will cause it to get stripped from the output file
+         below.  */
+      s = bfd_get_section_by_name (dynobj, ".rela.got");
+      if (s != NULL)
+	s->_raw_size = 0;
+    }
+
+  /* If this is a -Bsymbolic shared link, then we need to discard all
+     PC relative relocs against symbols defined in a regular object.
+     We allocated space for them in the check_relocs routine, but we
+     will not fill them in in the relocate_section routine.  */
+  if (info->shared && info->symbolic)
+    elf_s390_link_hash_traverse (elf_s390_hash_table (info),
+				 elf_s390_discard_copies,
+				 (PTR) NULL);
+
+
+  /* The check_relocs and adjust_dynamic_symbol entry points have
+     determined the sizes of the various dynamic sections.  Allocate
+     memory for them.  */
+  plt = false;
+  reltext = false;
+  relocs = false;
+  for (s = dynobj->sections; s != NULL; s = s->next)
+    {
+      const char *name;
+      boolean strip;
+
+      if ((s->flags & SEC_LINKER_CREATED) == 0)
+	continue;
+
+      /* It's OK to base decisions on the section name, because none
+	 of the dynobj section names depend upon the input files.  */
+      name = bfd_get_section_name (dynobj, s);
+
+      strip = false;
+
+      if (strcmp (name, ".plt") == 0)
+	{
+	  if (s->_raw_size == 0)
+	    {
+	      /* Strip this section if we don't need it; see the
+                 comment below.  */
+	      strip = true;
+	    }
+	  else
+	    {
+	      /* Remember whether there is a PLT.  */
+	      plt = true;
+	    }
+	}
+
+      else if (strncmp (name, ".rela", 5) == 0)
+	{
+	  if (s->_raw_size == 0)
+	    {
+	      /* If we don't need this section, strip it from the
+		 output file.  This is to handle .rela.bss and
+		 .rel.plt.  We must create it in
+		 create_dynamic_sections, because it must be created
+		 before the linker maps input sections to output
+		 sections.  The linker does that before
+		 adjust_dynamic_symbol is called, and it is that
+		 function which decides whether anything needs to go
+		 into these sections.  */
+	      strip = true;
+	    }
+	  else
+	    {
+	      asection *target;
+
+	      /* Remember whether there are any reloc sections other
+                 than .rela.plt.  */
+	      if (strcmp (name, ".rela.plt") != 0)
+		{
+		  const char *outname;
+
+		  relocs = true;
+
+		  /* If this relocation section applies to a read only
+		     section, then we probably need a DT_TEXTREL
+		     entry.  The entries in the .rela.plt section
+		     really apply to the .got section, which we
+		     created ourselves and so know is not readonly.  */
+		  outname = bfd_get_section_name (output_bfd,
+						  s->output_section);
+		  target = bfd_get_section_by_name (output_bfd, outname + 5);
+		  if (target != NULL
+		      && (target->flags & SEC_READONLY) != 0
+		      && (target->flags & SEC_ALLOC) != 0)
+		    reltext = true;
+		}
+
+	      /* We use the reloc_count field as a counter if we need
+		 to copy relocs into the output file.  */
+	      s->reloc_count = 0;
+	    }
+	}
+      else if (strncmp (name, ".got", 4) != 0)
+	{
+	  /* It's not one of our sections, so don't allocate space.  */
+	  continue;
+	}
+
+      if (strip)
+	{
+	  asection **spp;
+
+	  for (spp = &s->output_section->owner->sections;
+	       *spp != s->output_section;
+	       spp = &(*spp)->next)
+	    ;
+	  *spp = s->output_section->next;
+	  --s->output_section->owner->section_count;
+
+	  continue;
+	}
+
+      /* Allocate memory for the section contents.  */
+      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+      if (s->contents == NULL && s->_raw_size != 0)
+	return false;
+    }
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      /* Add some entries to the .dynamic section.  We fill in the
+	 values later, in elf32_s390_finish_dynamic_sections, but we
+	 must add the entries now so that we get the correct size for
+	 the .dynamic section.  The DT_DEBUG entry is filled in by the
+	 dynamic linker and used by the debugger.  */
+      if (! info->shared)
+	{
+	  if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+	    return false;
+	}
+
+      if (plt)
+	{
+	  if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
+	      || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+	      || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+	      || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+	    return false;
+	}
+
+      if (relocs)
+        {
+          if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
+              || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
+              || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
+					    sizeof (Elf32_External_Rela)))
+	    return false;
+         }
+
+      if (reltext)
+	{
+	  if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+	    return false;
+	}
+    }
+
+  return true;
+}
+
+/* This function is called via elf_s390_link_hash_traverse if we are
+   creating a shared object with -Bsymbolic.  It discards the space
+   allocated to copy PC relative relocs against symbols which are
+   defined in regular objects.  We allocated space for them in the
+   check_relocs routine, but we won't fill them in in the
+   relocate_section routine.  */
+
+/*ARGSUSED*/
+static boolean
+elf_s390_discard_copies (h, ignore)
+     struct elf_s390_link_hash_entry *h;
+     PTR ignore;
+{
+  struct elf_s390_pcrel_relocs_copied *s;
+
+  /* We only discard relocs for symbols defined in a regular object.  */
+  if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+    return true;
+
+  for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+    s->section->_raw_size -= s->count * sizeof (Elf32_External_Rela);
+
+  return true;
+}
+/* Relocate a 390 ELF section.  */
+
+static boolean
+elf32_s390_relocate_section (output_bfd, info, input_bfd, input_section,
+			      contents, relocs, local_syms, local_sections)
+     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;
+{
+  bfd *dynobj;
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes;
+  bfd_vma *local_got_offsets;
+  asection *sgot;
+  asection *splt;
+  asection *sreloc;
+  Elf_Internal_Rela *rel;
+  Elf_Internal_Rela *relend;
+
+  dynobj = elf_hash_table (info)->dynobj;
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (input_bfd);
+  local_got_offsets = elf_local_got_offsets (input_bfd);
+
+  sgot = NULL;
+  splt = NULL;
+  sreloc = NULL;
+
+  rel = relocs;
+  relend = relocs + input_section->reloc_count;
+  for (; rel < relend; rel++)
+    {
+      int r_type;
+      reloc_howto_type *howto;
+      unsigned long r_symndx;
+      struct elf_link_hash_entry *h;
+      Elf_Internal_Sym *sym;
+      asection *sec;
+      bfd_vma relocation;
+      bfd_reloc_status_type r;
+
+      r_type = ELF32_R_TYPE (rel->r_info);
+      if (r_type < 0 || r_type >= (int) R_390_max)
+	{
+	  bfd_set_error (bfd_error_bad_value);
+	  return false;
+	}
+      howto = _bfd_s390_elf_howto_table + r_type;
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+
+      if (info->relocateable)
+	{
+	  /* This is a relocateable link.  We don't have to change
+	     anything, unless the reloc is against a section symbol,
+	     in which case we have to adjust according to where the
+	     section symbol winds up in the output section.  */
+	  if (r_symndx < symtab_hdr->sh_info)
+	    {
+	      sym = local_syms + r_symndx;
+	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+		{
+		  sec = local_sections[r_symndx];
+		  rel->r_addend += sec->output_offset + sym->st_value;
+		}
+	    }
+
+	  continue;
+	}
+
+      /* This is a final link.  */
+      h = NULL;
+      sym = NULL;
+      sec = NULL;
+      if (r_symndx < symtab_hdr->sh_info)
+	{
+	  sym = local_syms + r_symndx;
+	  sec = local_sections[r_symndx];
+	  relocation = (sec->output_section->vma
+			+ sec->output_offset
+			+ sym->st_value);
+	}
+      else
+	{
+	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+	  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 (h->root.type == bfd_link_hash_defined
+	      || h->root.type == bfd_link_hash_defweak)
+	    {
+	      sec = h->root.u.def.section;
+	      if (r_type == R_390_GOTPC
+		  || ((r_type == R_390_PLT16DBL ||
+                       r_type == R_390_PLT32)
+		      && h->plt.offset != (bfd_vma) -1)
+		  || ((r_type == R_390_GOT12 ||
+                       r_type == R_390_GOT16 ||
+                       r_type == R_390_GOT32)
+		      && elf_hash_table (info)->dynamic_sections_created
+		      && (! info->shared
+			  || (! info->symbolic && h->dynindx != -1)
+			  || (h->elf_link_hash_flags
+			      & ELF_LINK_HASH_DEF_REGULAR) == 0))
+		  || (info->shared
+		      && ((! info->symbolic && h->dynindx != -1)
+			  || (h->elf_link_hash_flags
+			      & ELF_LINK_HASH_DEF_REGULAR) == 0)
+		      && ( r_type == R_390_8 ||
+			   r_type == R_390_16 ||
+                           r_type == R_390_32 ||
+                           ((r_type == R_390_PC16 ||
+                             r_type == R_390_PC16DBL ||
+                             r_type == R_390_PC32) &&
+                            strcmp (h->root.root.string,
+                                    "_GLOBAL_OFFSET_TABLE_") != 0))))
+		{
+		  /* In these cases, we don't need the relocation
+                     value.  We check specially because in some
+                     obscure cases sec->output_section will be NULL.  */
+		  relocation = 0;
+		}
+	      else if (sec->output_section == NULL)
+		{
+		  (*_bfd_error_handler)
+		    ("%s: warning: unresolvable relocation against symbol `%s' from %s section",
+		     bfd_get_filename (input_bfd), h->root.root.string,
+		     bfd_get_section_name (input_bfd, input_section));
+		  relocation = 0;
+		}
+	      else
+		relocation = (h->root.u.def.value
+			      + sec->output_section->vma
+			      + sec->output_offset);
+	    }
+	  else if (h->root.type == bfd_link_hash_undefweak)
+	    relocation = 0;
+	  else if (info->shared && !info->symbolic)
+	    relocation = 0;
+	  else
+	    {
+	      if (! ((*info->callbacks->undefined_symbol)
+		     (info, h->root.root.string, input_bfd,
+		      input_section, rel->r_offset,
+		      (!info->shared || info->no_undefined))))
+		return false;
+	      relocation = 0;
+	    }
+	}
+
+      switch (r_type)
+	{
+        case R_390_GOT12:
+        case R_390_GOT16:
+        case R_390_GOT32:
+          /* Relocation is to the entry for this symbol in the global
+             offset table.  */
+          if (sgot == NULL)
+            {
+              sgot = bfd_get_section_by_name (dynobj, ".got");
+              BFD_ASSERT (sgot != NULL);
+            }
+
+          if (h != NULL)
+            {
+              bfd_vma off;
+
+              off = h->got.offset;
+              BFD_ASSERT (off != (bfd_vma) -1);
+
+              if (! elf_hash_table (info)->dynamic_sections_created
+                  || (info->shared
+                      && (info->symbolic || h->dynindx == -1)
+                      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+                {
+                  /* This is actually a static link, or it is a
+                     -Bsymbolic link and the symbol is defined
+                     locally, or the symbol was forced to be local
+                     because of a version file.  We must initialize
+                     this entry in the global offset table.  Since the
+                     offset must always be a multiple of 2, we use the
+                     least significant bit to record whether we have
+                     initialized it already.
+
+                     When doing a dynamic link, we create a .rel.got
+                     relocation entry to initialize the value.  This
+                     is done in the finish_dynamic_symbol routine.  */
+                  if ((off & 1) != 0)
+                    off &= ~1;
+                  else
+                    {
+		      bfd_put_32 (output_bfd, relocation,
+				  sgot->contents + off);
+                      h->got.offset |= 1;
+                    }
+                }
+	      relocation = sgot->output_offset + off;
+            }
+          else
+            {
+              bfd_vma off;
+
+              BFD_ASSERT (local_got_offsets != NULL
+                          && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+              off = local_got_offsets[r_symndx];
+
+              /* The offset must always be a multiple of 4.  We use
+                 the least significant bit to record whether we have
+                 already generated the necessary reloc.  */
+              if ((off & 1) != 0)
+                off &= ~1;
+              else
+                {
+                  bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+
+                  if (info->shared)
+                    {
+                      asection *srelgot;
+                      Elf_Internal_Rela outrel;
+
+                      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+                      BFD_ASSERT (srelgot != NULL);
+
+                      outrel.r_offset = (sgot->output_section->vma
+                                         + sgot->output_offset
+                                         + off);
+                      outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
+		      outrel.r_addend = relocation;
+                      bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+                                                (((Elf32_External_Rela *)
+                                                  srelgot->contents)
+                                                 + srelgot->reloc_count));
+                      ++srelgot->reloc_count;
+                    }
+
+                  local_got_offsets[r_symndx] |= 1;
+                }
+
+	      relocation = sgot->output_offset + off;
+            }
+
+
+          break;
+ 
+        case R_390_GOTOFF:
+          /* Relocation is relative to the start of the global offset
+             table.  */
+
+          if (sgot == NULL)
+            {
+              sgot = bfd_get_section_by_name (dynobj, ".got");
+              BFD_ASSERT (sgot != NULL);
+            }
+
+          /* Note that sgot->output_offset is not involved in this
+             calculation.  We always want the start of .got.  If we
+             defined _GLOBAL_OFFSET_TABLE in a different way, as is
+             permitted by the ABI, we might have to change this
+             calculation.  */
+          relocation -= sgot->output_section->vma;
+
+          break;
+
+        case R_390_GOTPC:
+          /* Use global offset table as symbol value.  */
+
+          if (sgot == NULL)
+            {
+              sgot = bfd_get_section_by_name (dynobj, ".got");
+              BFD_ASSERT (sgot != NULL);
+            }
+
+          relocation = sgot->output_section->vma;
+
+          break;
+
+        case R_390_PLT16DBL:
+        case R_390_PLT32:
+          /* Relocation is to the entry for this symbol in the
+             procedure linkage table.  */
+
+          /* Resolve a PLT32 reloc against a local symbol directly,
+             without using the procedure linkage table.  */
+          if (h == NULL)
+            break;
+
+          if (h->plt.offset == (bfd_vma) -1)
+            {
+              /* We didn't make a PLT entry for this symbol.  This
+                 happens when statically linking PIC code, or when
+                 using -Bsymbolic.  */
+              break;
+            }
+
+          if (splt == NULL)
+            {
+              splt = bfd_get_section_by_name (dynobj, ".plt");
+              BFD_ASSERT (splt != NULL);
+            }
+
+          relocation = (splt->output_section->vma
+                        + splt->output_offset
+                        + h->plt.offset);
+
+          break;
+
+        case R_390_8:
+        case R_390_16:
+        case R_390_32:
+        case R_390_PC16:
+        case R_390_PC16DBL:
+        case R_390_PC32:
+          if (info->shared
+              && ((r_type != R_390_PC16 &&
+                   r_type != R_390_PC16DBL &&
+                   r_type != R_390_PC32)
+                  || (h != NULL
+                      && h->dynindx != -1
+                      && (! info->symbolic
+                          || (h->elf_link_hash_flags
+                              & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+            {
+              Elf_Internal_Rela outrel;
+              boolean skip, relocate;
+
+              /* When generating a shared object, these relocations
+                 are copied into the output file to be resolved at run
+                 time.  */
+
+              if (sreloc == NULL)
+                {
+                  const char *name;
+
+                  name = (bfd_elf_string_from_elf_section
+                          (input_bfd,
+                           elf_elfheader (input_bfd)->e_shstrndx,
+                           elf_section_data (input_section)->rel_hdr.sh_name));
+                  if (name == NULL)
+                    return false;
+
+                  BFD_ASSERT (strncmp (name, ".rela", 5) == 0
+                              && strcmp (bfd_get_section_name (input_bfd,
+                                                               input_section),
+                                         name + 5) == 0);
+
+                  sreloc = bfd_get_section_by_name (dynobj, name);
+                  BFD_ASSERT (sreloc != NULL);
+                }
+
+              skip = false;
+
+              if (elf_section_data (input_section)->stab_info == NULL)
+                outrel.r_offset = rel->r_offset;
+              else
+                {
+                  bfd_vma off;
+
+                  off = (_bfd_stab_section_offset
+                         (output_bfd, &elf_hash_table (info)->stab_info,
+                          input_section,
+                          &elf_section_data (input_section)->stab_info,
+                          rel->r_offset));
+                  if (off == (bfd_vma) -1)
+                    skip = true;
+                  outrel.r_offset = off;
+                }
+
+              outrel.r_offset += (input_section->output_section->vma
+                                  + input_section->output_offset);
+
+              if (skip)
+                {
+                  memset (&outrel, 0, sizeof outrel);
+                  relocate = false;
+                }
+              else if (r_type == R_390_PC16 ||
+                       r_type == R_390_PC16DBL ||
+                       r_type == R_390_PC32)
+                {
+                  BFD_ASSERT (h != NULL && h->dynindx != -1);
+                  if ((input_section->flags & SEC_ALLOC) != 0)
+                    relocate = false;
+                  else
+                    relocate = true;
+                  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+		  outrel.r_addend = relocation + rel->r_addend;
+                }
+              else
+                {
+                  /* h->dynindx may be -1 if this symbol was marked to
+                     become local.  */
+                  if (h == NULL
+                      || ((info->symbolic || h->dynindx == -1)
+                          && (h->elf_link_hash_flags
+                              & ELF_LINK_HASH_DEF_REGULAR) != 0))
+                    {
+                      relocate = true;
+                      outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
+		      outrel.r_addend = relocation + rel->r_addend;
+                    }
+		  else
+		    {
+		      BFD_ASSERT (h->dynindx != -1);
+		      if ((input_section->flags & SEC_ALLOC) != 0)
+			relocate = false;
+		      else
+			relocate = true;
+		      outrel.r_info = ELF32_R_INFO (h->dynindx, R_390_32);
+		      outrel.r_addend = relocation + rel->r_addend;
+		    }
+                }
+
+              bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+                                        (((Elf32_External_Rela *)
+                                          sreloc->contents)
+                                         + sreloc->reloc_count));
+              ++sreloc->reloc_count;
+
+              /* If this reloc is against an external symbol, we do
+                 not want to fiddle with the addend.  Otherwise, we
+                 need to include the symbol value so that it becomes
+                 an addend for the dynamic reloc.  */
+              if (! relocate)
+                continue;
+            }
+
+          break;
+
+        default:
+          break;
+        }
+
+      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+				      contents, rel->r_offset,
+				      relocation, rel->r_addend);
+
+      if (r != bfd_reloc_ok)
+	{
+	  switch (r)
+	    {
+	    default:
+	    case bfd_reloc_outofrange:
+	      abort ();
+	    case bfd_reloc_overflow:
+	      {
+		const char *name;
+
+		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)
+		      return false;
+		    if (*name == '\0')
+		      name = bfd_section_name (input_bfd, sec);
+		  }
+		if (! ((*info->callbacks->reloc_overflow)
+		       (info, name, howto->name, (bfd_vma) 0,
+			input_bfd, input_section, rel->r_offset)))
+		  return false;
+	      }
+	      break;
+	    }
+	}
+    }
+
+  return true;
+}
+
+/* Finish up dynamic symbol handling.  We set the contents of various
+   dynamic sections here.  */
+
+static boolean
+elf32_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+     struct elf_link_hash_entry *h;
+     Elf_Internal_Sym *sym;
+{
+  bfd *dynobj;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  if (h->plt.offset != (bfd_vma) -1)
+    {
+      asection *splt;
+      asection *srela;
+      Elf_Internal_Rela rela;
+      bfd_vma relative_offset;
+      bfd_vma got_offset;
+      bfd_vma plt_index;
+      asection *sgot;
+
+      /* This symbol has an entry in the procedure linkage table.  Set
+         it up.  */
+
+      BFD_ASSERT (h->dynindx != -1);
+
+      sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+      BFD_ASSERT (sgot != NULL);
+      splt = bfd_get_section_by_name (dynobj, ".plt");
+      srela = bfd_get_section_by_name (dynobj, ".rela.plt");
+      BFD_ASSERT (splt != NULL && srela != NULL);
+
+
+      /* Calc. index no. Current offset - size first entry/ entry size */
+      plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
+
+      /* Offset in GOT is PLT index plus GOT headers(3) times 4, addr & GOT addr */
+      got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
+
+      relative_offset =  0;
+      /* S390 uses halfwords for relative branch calc! */
+      relative_offset -= (PLT_FIRST_ENTRY_SIZE + 
+                           (PLT_ENTRY_SIZE * plt_index) + 18)/2;
+      /* If offset is > 32768, branch to a previous branch */
+      /* 390 can only handle +-64 K jumps.                 */
+      if ( -32768 > (int)relative_offset )
+          relative_offset = -((32768/PLT_ENTRY_SIZE)*PLT_ENTRY_SIZE);
+
+      /* Fill in the entry in the procedure linkage table.  */
+      if (!info->shared)
+       {
+        bfd_put_32 (output_bfd, PLT_ENTRY_WORD0,
+                    splt->contents + h->plt.offset);
+        bfd_put_32 (output_bfd, PLT_ENTRY_WORD1,
+                    splt->contents + h->plt.offset + 4);
+        bfd_put_32 (output_bfd, PLT_ENTRY_WORD2,
+                    splt->contents + h->plt.offset + 8);
+        bfd_put_32 (output_bfd, PLT_ENTRY_WORD3,
+                    splt->contents + h->plt.offset + 12);
+        bfd_put_32 (output_bfd, PLT_ENTRY_WORD4,
+                    splt->contents + h->plt.offset + 16);
+        bfd_put_32 (output_bfd, 0+(relative_offset << 16),
+                    splt->contents + h->plt.offset + 20);
+        bfd_put_32 (output_bfd,
+                    (sgot->output_section->vma +
+                     sgot->output_offset +
+                     got_offset),
+                     splt->contents + h->plt.offset + 24);
+        /* Insert offset into  reloc. table here */
+        bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
+                    splt->contents + h->plt.offset + 28);
+       }
+      else
+       {
+        bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD0,
+		    splt->contents + h->plt.offset);
+        bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD1,
+		    splt->contents + h->plt.offset + 4);
+        bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD2,
+		    splt->contents + h->plt.offset + 8);
+        bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD3, 
+		    splt->contents + h->plt.offset + 12);
+        bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD4,
+		    splt->contents + h->plt.offset + 16);
+        bfd_put_32 (output_bfd, 0+(relative_offset << 16),
+		    splt->contents + h->plt.offset + 20);
+        bfd_put_32 (output_bfd, got_offset,
+		    splt->contents + h->plt.offset + 24);
+        /* Insert offset into  reloc. table here */
+        bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
+		    splt->contents + h->plt.offset + 28);
+       }
+
+      /* Fill in the entry in the .rela.plt section.  */
+      rela.r_offset = (sgot->output_section->vma
+		       + sgot->output_offset
+		       + got_offset);
+      rela.r_info = ELF32_R_INFO (h->dynindx, R_390_JMP_SLOT);
+      rela.r_addend = 0;
+      bfd_elf32_swap_reloca_out (output_bfd, &rela,
+				 ((Elf32_External_Rela *) srela->contents
+				  + plt_index ));
+
+      /* Fill in the entry in the global offset table.  */
+      /* Points to instruction after GOT offset */
+      bfd_put_32 (output_bfd,
+		  (splt->output_section->vma
+		   + splt->output_offset
+		   + h->plt.offset
+		   + 12),
+		  sgot->contents + got_offset);
+
+
+      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+	{
+	  /* Mark the symbol as undefined, rather than as defined in
+	     the .plt section.  Leave the value alone.  */
+	  sym->st_shndx = SHN_UNDEF;
+	}
+    }
+
+  if (h->got.offset != (bfd_vma) -1)
+    {
+      asection *sgot;
+      asection *srela;
+      Elf_Internal_Rela rela;
+
+      /* This symbol has an entry in the global offset table.  Set it
+         up.  */
+
+      sgot = bfd_get_section_by_name (dynobj, ".got");
+      srela = bfd_get_section_by_name (dynobj, ".rela.got");
+      BFD_ASSERT (sgot != NULL && srela != NULL);
+
+      rela.r_offset = (sgot->output_section->vma
+		       + sgot->output_offset
+		       + (h->got.offset &~ 1));
+
+      /* If this is a -Bsymbolic link, and the symbol is defined
+	 locally, we just want to emit a RELATIVE reloc.  Likewise if
+	 the symbol was forced to be local because of a version file.
+	 The entry in the global offset table will already have been
+	 initialized in the relocate_section function.  */
+      if (info->shared
+	  && (info->symbolic || h->dynindx == -1)
+	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+        {
+          rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
+          rela.r_addend = (h->root.u.def.value
+                           + h->root.u.def.section->output_section->vma
+                           + h->root.u.def.section->output_offset);
+        }
+      else
+	{
+	  bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+	  rela.r_info = ELF32_R_INFO (h->dynindx, R_390_GLOB_DAT);
+          rela.r_addend = 0;
+        }
+
+      bfd_elf32_swap_reloca_out (output_bfd, &rela,
+				 ((Elf32_External_Rela *) srela->contents
+				  + srela->reloc_count));
+      ++srela->reloc_count;
+    }
+
+  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+    {
+      asection *s;
+      Elf_Internal_Rela rela;
+
+      /* This symbols needs a copy reloc.  Set it up.  */
+
+      BFD_ASSERT (h->dynindx != -1
+		  && (h->root.type == bfd_link_hash_defined
+		      || h->root.type == bfd_link_hash_defweak));
+
+
+      s = bfd_get_section_by_name (h->root.u.def.section->owner,
+				   ".rela.bss");
+      BFD_ASSERT (s != NULL);
+
+      rela.r_offset = (h->root.u.def.value
+		       + h->root.u.def.section->output_section->vma
+		       + h->root.u.def.section->output_offset);
+      rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY);
+      rela.r_addend = 0;
+      bfd_elf32_swap_reloca_out (output_bfd, &rela,
+				 ((Elf32_External_Rela *) s->contents
+				  + s->reloc_count));
+      ++s->reloc_count;
+    }
+
+  /* Mark some specially defined symbols as absolute.  */
+  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
+      || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0){
+    sym->st_shndx = SHN_ABS;
+
+  }
+
+  return true;
+}
+
+/* Finish up the dynamic sections.  */
+
+static boolean
+elf32_s390_finish_dynamic_sections (output_bfd, info)
+     bfd *output_bfd;
+     struct bfd_link_info *info;
+{
+  bfd *dynobj;
+  asection *sdyn;
+  asection *sgot;
+
+  dynobj = elf_hash_table (info)->dynobj;
+
+  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+  BFD_ASSERT (sgot != NULL);
+  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      asection *splt;
+      Elf32_External_Dyn *dyncon, *dynconend;
+
+      splt = bfd_get_section_by_name (dynobj, ".plt");
+      BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+      dyncon = (Elf32_External_Dyn *) sdyn->contents;
+      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+      for (; dyncon < dynconend; dyncon++)
+	{
+	  Elf_Internal_Dyn dyn;
+	  const char *name;
+	  boolean size;
+
+	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+	  switch (dyn.d_tag)
+	    {
+	    case DT_PLTGOT:   name = ".got"; size = false; break;
+	    case DT_PLTRELSZ: name = ".rela.plt"; size = true; break;
+	    case DT_JMPREL:   name = ".rela.plt"; size = false; break;
+	    default:	  name = NULL; size = false; break;
+	    }
+
+	  if (name != NULL)
+	    {
+	      asection *s;
+
+	      s = bfd_get_section_by_name (output_bfd, name);
+	      if (s == NULL)
+		dyn.d_un.d_val = 0;
+	      else
+		{
+		  if (! size)
+		    dyn.d_un.d_ptr = s->vma;
+		  else
+		    {
+		      if (s->_cooked_size != 0)
+			dyn.d_un.d_val = s->_cooked_size;
+		      else
+			dyn.d_un.d_val = s->_raw_size;
+		    }
+		}
+	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+	    }
+	}
+      /* Fill in the special first entry in the procedure linkage table,
+      */
+      if (splt->_raw_size > 0)
+	{
+          memset (splt->contents, 0, PLT_FIRST_ENTRY_SIZE);
+          if (info->shared)
+           {
+	      bfd_put_32 (output_bfd, PLT_PIC_FIRST_ENTRY_WORD0,
+		          splt->contents );
+	      bfd_put_32 (output_bfd, PLT_PIC_FIRST_ENTRY_WORD1,
+		          splt->contents +4 );
+	      bfd_put_32 (output_bfd, PLT_PIC_FIRST_ENTRY_WORD2,
+		          splt->contents +8 );
+	      bfd_put_32 (output_bfd, PLT_PIC_FIRST_ENTRY_WORD3,
+		          splt->contents +12 );
+	      bfd_put_32 (output_bfd, PLT_PIC_FIRST_ENTRY_WORD4,
+		          splt->contents +16 );
+           }
+          else
+           {
+              bfd_put_32 (output_bfd, PLT_FIRST_ENTRY_WORD0,
+                          splt->contents );
+              bfd_put_32 (output_bfd, PLT_FIRST_ENTRY_WORD1,
+                          splt->contents +4 );
+              bfd_put_32 (output_bfd, PLT_FIRST_ENTRY_WORD2,
+                          splt->contents +8 );
+              bfd_put_32 (output_bfd, PLT_FIRST_ENTRY_WORD3,
+                          splt->contents +12 );
+              bfd_put_32 (output_bfd, PLT_FIRST_ENTRY_WORD4,
+                          splt->contents +16 );
+              bfd_put_32 (output_bfd, PLT_FIRST_ENTRY_WORD5,
+                          splt->contents +20 );
+              bfd_put_32 (output_bfd,
+                          sgot->output_section->vma + sgot->output_offset,
+                          splt->contents + 24);
+           }
+	}
+
+      elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+    }
+
+  /* Set the first entry in the global offset table to the address of
+     the dynamic section.  */
+  if (sgot->_raw_size > 0)
+    {
+      if (sdyn == NULL)
+	bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
+      else
+	bfd_put_32 (output_bfd,
+		    sdyn->output_section->vma + sdyn->output_offset,
+		    sgot->contents);
+
+      /* One entry for shared object struct ptr */
+      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
+      /* One entry for _dl_runtime_resolve */
+      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
+    }
+
+  elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+
+  return true;
+}
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
+static boolean
+elf32_s390_merge_private_bfd_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  boolean error;
+
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  error = false;
+
+  if (error)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+
+  return true;
+}
+
+#define TARGET_BIG_SYM	bfd_elf32_s390_vec
+#define TARGET_BIG_NAME	"elf32-s390"
+#define ELF_ARCH	bfd_arch_s390
+#define ELF_MACHINE_CODE EM_S390
+#define ELF_MAXPAGESIZE 0x1000
+
+#define bfd_elf32_bfd_reloc_type_lookup	elf32_s390_reloc_type_lookup
+#define elf_info_to_howto		elf32_s390_info_to_howto
+#define elf_backend_create_dynamic_sections \
+					_bfd_elf_create_dynamic_sections
+#define elf_backend_check_relocs	elf32_s390_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+					elf32_s390_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+					elf32_s390_size_dynamic_sections
+#define elf_backend_relocate_section	elf32_s390_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+					elf32_s390_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+					elf32_s390_finish_dynamic_sections
+#define bfd_elf32_bfd_merge_private_bfd_data \
+					elf32_s390_merge_private_bfd_data
+#define bfd_elf32_bfd_link_hash_table_create \
+					elf_s390_link_hash_table_create
+#define bfd_elf32_bfd_is_local_label_name \
+					elf_s390_is_local_label_name
+
+/***
+#define elf_backend_object_p            elf32_s390_object_p
+#define elf_backend_final_write_processing \
+					elf32_s390_final_write_processing
+***/
+/*
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+*/
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size   12
+#define elf_backend_plt_header_size   PLT_ENTRY_SIZE
+
+#include "elf32-target.h"
diff -u -r --new-file gdb-5.0/bfd/libbfd.h gdb-5.0-s390/bfd/libbfd.h
--- gdb-5.0/bfd/libbfd.h	Sat Apr  8 02:10:49 2000
+++ gdb-5.0-s390/bfd/libbfd.h	Tue Jul 18 19:16:44 2000
@@ -866,6 +866,16 @@
   "BFD_RELOC_TIC54X_23",
   "BFD_RELOC_TIC54X_16_OF_23",
   "BFD_RELOC_TIC54X_MS7_OF_23",
+  "BFD_RELOC_390_12",
+  "BFD_RELOC_390_GOT12",
+  "BFD_RELOC_390_GOT32",
+  "BFD_RELOC_390_PLT32",
+  "BFD_RELOC_390_COPY",
+  "BFD_RELOC_390_GLOB_DAT",
+  "BFD_RELOC_390_JMP_SLOT",
+  "BFD_RELOC_390_RELATIVE",
+  "BFD_RELOC_390_GOTOFF",
+  "BFD_RELOC_390_GOTPC",  
   "BFD_RELOC_FR30_48",
   "BFD_RELOC_FR30_20",
   "BFD_RELOC_FR30_6_IN_4",
diff -u -r --new-file gdb-5.0/bfd/targets.c gdb-5.0-s390/bfd/targets.c
--- gdb-5.0/bfd/targets.c	Fri Apr  7 19:06:58 2000
+++ gdb-5.0-s390/bfd/targets.c	Tue Jul 18 19:16:44 2000
@@ -521,6 +521,7 @@
 extern const bfd_target bfd_elf32_hppa_vec;
 extern const bfd_target bfd_elf32_i370_vec;
 extern const bfd_target bfd_elf32_i386_vec;
+extern const bfd_target bfd_elf32_s390_vec;
 extern const bfd_target bfd_elf32_i860_vec;
 extern const bfd_target bfd_elf32_i960_vec;
 extern const bfd_target bfd_elf32_little_generic_vec;
@@ -883,7 +884,7 @@
 	&vms_vax_vec,
 	&we32kcoff_vec,
 	&z8kcoff_vec,
-
+	&bfd_elf32_s390_vec,      
 #endif /* not SELECT_VECS */
 
 /* Always support S-records, for convenience.  */
diff -u -r --new-file gdb-5.0/bfd/trad-core.c gdb-5.0-s390/bfd/trad-core.c
--- gdb-5.0/bfd/trad-core.c	Mon Feb 21 13:01:25 2000
+++ gdb-5.0-s390/bfd/trad-core.c	Wed Jul 26 00:09:16 2000
@@ -30,6 +30,9 @@
 
 #include <sys/user.h>		/* After a.out.h  */
 
+#ifdef __s390__
+#undef TRAD_HEADER /* problem with configure script */
+#endif
 #ifdef TRAD_HEADER
 #include TRAD_HEADER
 #endif
diff -u -r --new-file gdb-5.0/config.sub gdb-5.0-s390/config.sub
--- gdb-5.0/config.sub	Thu Feb 24 22:20:57 2000
+++ gdb-5.0-s390/config.sub	Tue Jul 18 19:16:38 2000
@@ -671,6 +671,11 @@
 	rtpc | rtpc-*)
 		basic_machine=romp-ibm
 		;;
+	s390)
+		basic_machine=$basic_machine-ibm
+		;;
+	s390-*)
+		;;
 	sa29200)
 		basic_machine=a29k-amd
 		os=-udi
diff -u -r --new-file gdb-5.0/configure.in gdb-5.0-s390/configure.in
--- gdb-5.0/configure.in	Thu May 18 07:02:10 2000
+++ gdb-5.0-s390/configure.in	Tue Jul 18 19:16:38 2000
@@ -291,6 +291,9 @@
     i370-*-*)
       host_makefile_frag="${host_makefile_frag} config/mh-i370pic"
       ;;
+    s390-*)
+      host_makefile_frag="${host_makefile_frag} config/mh-390pic"
+      ;;  
     sparc64-*-*)
       host_makefile_frag="${host_makefile_frag} config/mh-sparcpic"
       ;;
diff -u -r --new-file gdb-5.0/gdb/breakpoint.c gdb-5.0-s390/gdb/breakpoint.c
--- gdb-5.0/gdb/breakpoint.c	Thu Mar 30 20:54:28 2000
+++ gdb-5.0-s390/gdb/breakpoint.c	Tue Jul 18 19:16:39 2000
@@ -1486,7 +1486,9 @@
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
+#ifndef __s390__  
     b->inserted = 0;
+#endif
 
     switch (b->type)
       {
@@ -1507,7 +1509,9 @@
       case bp_access_watchpoint:
 
 	/* Likewise for watchpoints on local expressions.  */
+#ifndef __s390__  
 	if (b->exp_valid_block != NULL)
+#endif
 	  delete_breakpoint (b);
 	break;
       default:
diff -u -r --new-file gdb-5.0/gdb/config/s390/linux.mh gdb-5.0-s390/gdb/config/s390/linux.mh
--- gdb-5.0/gdb/config/s390/linux.mh	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/config/s390/linux.mh	Tue Jul 18 19:16:41 2000
@@ -0,0 +1,10 @@
+# Host: S390, running Linux
+
+XM_FILE= xm-linux.h
+XDEPFILES= ser-tcp.o
+XM_CLIBS=
+
+NAT_FILE= ../nm-sysv4.h
+NATDEPFILES= solib.o corelow.o # infptrace.o inftarg.o fork-child.o core-aout.o core-regset.o
+
+GDBSERVER_DEPFILES= low-linux.o
diff -u -r --new-file gdb-5.0/gdb/config/s390/linux.mt gdb-5.0-s390/gdb/config/s390/linux.mt
--- gdb-5.0/gdb/config/s390/linux.mt	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/config/s390/linux.mt	Thu Aug  3 21:23:47 2000
@@ -0,0 +1,2 @@
+# Target: S390 running Linux
+TM_FILE= tm-linux.h
diff -u -r --new-file gdb-5.0/gdb/config/s390/s390.mh gdb-5.0-s390/gdb/config/s390/s390.mh
--- gdb-5.0/gdb/config/s390/s390.mh	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/config/s390/s390.mh	Tue Jul 18 19:16:41 2000
@@ -0,0 +1,10 @@
+# Host: S390, running Linux
+
+XM_FILE= xm-linux.h
+XDEPFILES= ser-tcp.o
+XM_CLIBS=
+
+NAT_FILE= ../nm-sysv4.h
+NATDEPFILES= solib.o corelow.o infptrace.o s390-nat.o inftarg.o fork-child.o core-aout.o core-regset.o linux-thread.o
+
+GDBSERVER_DEPFILES= low-linux.o
diff -u -r --new-file gdb-5.0/gdb/config/s390/s390.mt gdb-5.0-s390/gdb/config/s390/s390.mt
--- gdb-5.0/gdb/config/s390/s390.mt	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/config/s390/s390.mt	Tue Jul 18 19:16:41 2000
@@ -0,0 +1,3 @@
+# Target: S390 with ELF
+TDEPFILES= s390-tdep.o
+TM_FILE= tm-s390.h
diff -u -r --new-file gdb-5.0/gdb/config/s390/tm-linux.h gdb-5.0-s390/gdb/config/s390/tm-linux.h
--- gdb-5.0/gdb/config/s390/tm-linux.h	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/config/s390/tm-linux.h	Thu Aug  3 21:23:47 2000
@@ -0,0 +1,26 @@
+/* Macro definitions for GDB for a Sparc running Linux.
+   Copyright 1989, 1992, 1994, 1995, 1998 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 "tm-linux.h"
+
+#endif /* TM_LINUX_H */
diff -u -r --new-file gdb-5.0/gdb/config/s390/tm-s390.h gdb-5.0-s390/gdb/config/s390/tm-s390.h
--- gdb-5.0/gdb/config/s390/tm-s390.h	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/config/s390/tm-s390.h	Tue Jul 18 19:16:41 2000
@@ -0,0 +1,328 @@
+/* Macro definitions for GDB on an S390.
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Ported by D.J. Barrow for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+#ifndef TM_S390_H
+#define TM_S390_H 1
+#ifdef __STDC__		/* Forward decl's for prototypes */
+struct frame_info;
+struct frame_saved_regs;
+struct type;
+struct value;
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifdef linux
+#include <asm/types.h>
+#include <asm/user.h>
+#include <asm/s390-gdbregs.h>
+#define BREAKPOINT S390_BREAKPOINT
+#define KERNEL_U_SIZE sizeof(struct user)
+#else
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+#endif /* linux */
+
+#ifndef offsetof
+#define offsetof(type, member) ( (int) & ((type*)0) -> member )
+#error "Do something about asm/s390-gdbregs.h"
+#endif
+
+
+
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* Used for example in valprint.c:print_floating() to enable checking
+   for NaN's */
+
+#define IEEE_FLOAT
+
+/* Number of traps that happen between exec'ing the shell to run an
+   inferior, and when we finally get to the inferior code.  This is 2
+   on most implementations. */
+
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+
+/* Stack grows downward.  */
+
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+struct frame_extra_info 
+{
+	int             initialised;
+	int             good_prologue;
+	CORE_ADDR       function_start;
+	CORE_ADDR       saved_pc_valid;
+	CORE_ADDR       saved_pc;
+	CORE_ADDR       sig_fixed_saved_pc_valid;
+	CORE_ADDR       sig_fixed_saved_pc;
+	__u32	        stack_bought; /* amount we decrement the stack pointer by */
+	int             has_frame_pointer; /* frame pointer needed for alloca */
+};
+/* Advance PC across any function entry prologue instructions to reach some
+   "real" code.  */
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(pc)  (pc) = s390_skip_prologue((pc),NULL,NULL,FALSE);
+
+
+extern CORE_ADDR s390_skip_prologue PARAMS((CORE_ADDR,struct frame_extra_info *,struct frame_info *,int));
+
+
+
+/*
+  Obviously ptrace for user program tracing cannot be allowed
+  mess with control registers (except per registers for hardware watchpoints),
+  when we add kernel debugging we may need to alter these macros.
+ */
+#define CANNOT_FETCH_REGISTER(regno) (((regno)>=FIRST_CR && (regno)<(FIRST_CR+9))||((regno)>=(FIRST_CR+12) && (regno)<=LAST_CR))
+#define CANNOT_STORE_REGISTER(regno)  CANNOT_FETCH_REGISTER(regno)
+
+
+
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+#define REGISTER_VIRTUAL_TYPE(N) \
+ (((unsigned)(N) - FP0_REGNUM) < NUM_FPRS ? builtin_type_double : builtin_type_int)
+
+
+
+/* Number of bytes of storage in the actual machine representation
+   for register N. */
+/* Note that the unsigned cast here forces the result of the
+   subtraction to very high positive values if N < FP0_REGNUM */
+
+#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < NUM_FPRS ? FPR_SIZE : 4 )
+
+/* Number of bytes of storage in the program's representation
+   for register N.  On the RS6000, all regs are 4 bytes
+   except the floating point regs which are 8-byte doubles.  */
+
+#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < NUM_FPRS ? FPR_SIZE : 4 )
+
+
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+#define DECR_PC_AFTER_BREAK 2
+
+/* Discard from the stack the innermost frame, 
+   restoring all saved registers.  */
+
+#define POP_FRAME	s390_pop_frame ()
+extern void s390_pop_frame PARAMS ((void));
+
+#define PUSH_DUMMY_FRAME	s390_push_dummy_frame ()
+extern void s390_push_dummy_frame PARAMS ((void));
+
+#define	PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+  sp = s390_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))
+extern CORE_ADDR s390_push_arguments PARAMS ((int, struct value **, CORE_ADDR,
+					 int, CORE_ADDR));
+
+/*
+  instruction sequence for call dummy is as follows
+  bras %r1,.+8      ; 0xA7150004   
+  long basraddr     ; 0x00000000
+  l    %r1,0(%r1)   ; 0x58101000
+  basr %r14,%r1     ; 0x0de1
+  breakpoint        ; 0x0001
+ */
+#define CALL_DUMMY {0xA7150004,0x00000000,0x58101000,0x0de10000|S390_BREAKPOINT_U16}
+#define CALL_DUMMY_LENGTH 16
+#define CALL_ADDR_OFFSET  4
+#define CALL_DUMMY_LOCATION     ON_STACK
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+/* This is a kludge because the macro in PC_IN_CALL_DUMMY macro in inferior.h */
+/* fails for us */
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \
+(INNER_THAN ((sp), (pc))&&INNER_THAN ((pc), (sp+4096))) 
+
+
+/*
+  We don't define CALL_DUMMY_BREAKPOINT_OFFSET 
+  as we already have a breakpoint inserted.
+*/
+
+/*
+  used to fix basraddr in CALL_DUMMY
+ */
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
+{ \
+	  *(long *)((char *)&dummyname[CALL_ADDR_OFFSET])=fun; \
+}
+
+#define STORE_STRUCT_RETURN(ADDR, SP)  write_register(GP0_REGNUM+2, (ADDR));
+/* Return number of bytes at start of arglist that are not really args.  */
+#define FRAME_ARGS_SKIP 0
+
+extern CORE_ADDR s390_frame_args_address PARAMS ((struct frame_info *));
+#define FRAME_ARGS_ADDRESS(FI) s390_frame_args_address (FI)
+
+#define FRAME_LOCALS_ADDRESS(FI)	FRAME_ARGS_ADDRESS(FI)
+#define FRAME_NUM_ARGS(fi) (-1)  /* We can't do this */
+/* Return number of bytes at start of arglist that are not really args.  */
+
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+/* In the following implementation for RS6000, we did *not* save sp. I am
+   not sure if it will be needed. The following macro takes care of gpr's
+   and fpr's only. */
+
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  s390_extract_return_value(TYPE,REGBUF,VALBUF)
+extern void s390_extract_return_value PARAMS ((struct type *, char [], char *));
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+ s390_store_return_value(TYPE,VALBUF)
+extern void s390_store_return_value PARAMS ((struct type *, char *));
+
+/* Return saved PC from a frame */
+#define FRAME_SAVED_PC(FRAME)  s390_frame_saved_pc (FRAME)
+extern unsigned long s390_frame_saved_pc PARAMS ((struct frame_info *));
+
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer. */
+
+#define FRAME_CHAIN(thisframe) s390_frame_chain (thisframe)
+CORE_ADDR s390_frame_chain PARAMS ((struct frame_info *));
+
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define	SAVED_PC_AFTER_CALL(frame) ADDR_BITS_REMOVE(read_register (RETADDR_REGNUM))
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+	(addr) = s390_register_u_addr ((blockend),(regno));
+
+extern int
+s390_register_u_addr PARAMS ((int, int));
+
+#define TARGET_WRITE_FP(val) s390_write_fp(val)
+void s390_write_fp PARAMS ((CORE_ADDR val));
+
+#define TARGET_READ_FP()   s390_read_fp()
+CORE_ADDR s390_read_fp  PARAMS (());
+
+/*
+  unfortunately my fix to ptrace(PC) to return a 31 bit address isn't
+  adequete because gdb frequently gets return addresses from the stack. 
+ */
+
+#define	INIT_EXTRA_FRAME_INFO(fromleaf, fi) s390_init_extra_frame_info((fromleaf),(fi))
+void s390_init_extra_frame_info (int fromleaf,struct frame_info *fi);
+
+
+#define	INIT_FRAME_PC_FIRST(fromleaf, fi) s390_init_frame_pc_first((fromleaf),(fi))
+void s390_init_pc_first (int fromleaf,struct frame_info *fi);
+
+void s390_frame_get_saved_regs (struct frame_info *fi);
+#define FRAME_INIT_SAVED_REGS(FI) s390_frame_get_saved_regs (FI);
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+
+#define FRAMELESS_FUNCTION_INVOCATION(FI) \
+  s390_frameless_function_invocation (FI)
+
+extern int s390_frameless_function_invocation PARAMS((struct frame_info *));
+/* WATCHPOINT SPECIFIC STUFF */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_STEPPABLE_WATCHPOINT 
+#define target_insert_watchpoint(addr, len, type)  \
+  s390_insert_watchpoint (inferior_pid, addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type)  \
+  s390_remove_watchpoint (inferior_pid, addr, len)
+
+extern int       watchAreaCnt;
+/* gdb if really stupid & calls this all the time without a
+   watchpoint even being set */
+#define STOPPED_BY_WATCHPOINT(W)  \
+  (watchAreaCnt&&s390_stopped_by_watchpoint (inferior_pid))
+
+extern CORE_ADDR
+s390_stopped_by_watchpoint PARAMS ((int));
+
+/*
+  Type can be 1 for a read_watchpoint or 2 for an access watchpoint.
+ */
+extern int
+s390_insert_watchpoint PARAMS ((int pid, CORE_ADDR addr, int len, int rw));
+extern int
+s390_remove_watchpoint PARAMS ((int pid, CORE_ADDR addr, int len));
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+	 (((type) == bp_hardware_watchpoint)|| \
+	 ((type) == bp_watchpoint)|| \
+	 ((type) == bp_read_watchpoint) || \
+         ((type) == bp_access_watchpoint)) 
+#endif /* ifndef TM_S390_H */
+
+
+
+
+
+
+
+
+
+
+
diff -u -r --new-file gdb-5.0/gdb/config/s390/xm-linux.h gdb-5.0-s390/gdb/config/s390/xm-linux.h
--- gdb-5.0/gdb/config/s390/xm-linux.h	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/config/s390/xm-linux.h	Thu Aug  3 21:23:47 2000
@@ -0,0 +1,36 @@
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989, 1992 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 XM_LINUX_H
+#define XM_LINUX_H
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+#define HAVE_TERMIOS
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+#define KERNEL_U_ADDR 0x0
+
+#define NEED_POSIX_SETPGID
+
+/* Need R_OK etc, but USG isn't defined.  */
+#include <unistd.h>
+
+#endif	/* #ifndef XM_LINUX_H */
diff -u -r --new-file gdb-5.0/gdb/configure.host gdb-5.0-s390/gdb/configure.host
--- gdb-5.0/gdb/configure.host	Mon May  1 18:30:55 2000
+++ gdb-5.0-s390/gdb/configure.host	Tue Jul 18 19:16:39 2000
@@ -164,5 +164,10 @@
 vax-*-bsd*)		gdb_host=vaxbsd ;;
 vax-*-ultrix2*)		gdb_host=vaxult2 ;;
 vax-*-ultrix*)		gdb_host=vaxult ;;
-
+s390-*-*)               gdb_host=s390 ;;
 esac
+
+
+
+
+
diff -u -r --new-file gdb-5.0/gdb/configure.tgt gdb-5.0-s390/gdb/configure.tgt
--- gdb-5.0/gdb/configure.tgt	Mon May  1 18:30:55 2000
+++ gdb-5.0-s390/gdb/configure.tgt	Tue Jul 18 19:16:39 2000
@@ -292,5 +292,6 @@
 
 z8k-*-coff*)		gdb_target=z8k ;;
 
+s390-*-*)               gdb_target=s390 ;;
 esac
 
diff -u -r --new-file gdb-5.0/gdb/s390-nat.c gdb-5.0-s390/gdb/s390-nat.c
--- gdb-5.0/gdb/s390-nat.c	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/s390-nat.c	Tue Jul 18 19:16:40 2000
@@ -0,0 +1,229 @@
+/* S390 native-dependent code for GDB, the GNU debugger.
+   Copyright 1999 Free Software Foundation, Inc
+   By D.J. Barrow for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+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 "tm.h"
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <sys/procfs.h>
+
+int s390_register_u_addr (int blockend,int regnum)
+{
+	int retval;
+
+	if(regnum>=GP0_REGNUM&&regnum<=GP_LAST_REGNUM)
+		retval=PT_GPR0+((regnum-GP0_REGNUM)*GPR_SIZE);
+	else if(regnum>=PSWM_REGNUM&&regnum<=PC_REGNUM)
+		retval=PT_PSWMASK+((regnum-PSWM_REGNUM)*PSW_MASK_SIZE);
+	else if(regnum==FPC_REGNUM)
+		retval=PT_FPC;
+	else if(regnum>=FP0_REGNUM&&regnum<=FPLAST_REGNUM)
+		retval=PT_FPR0_HI+((regnum-FP0_REGNUM)*FPR_SIZE);
+	else if(regnum>=FIRST_ACR&&regnum<=LAST_ACR)
+		retval=PT_ACR0+((regnum-FIRST_ACR)*ACR_SIZE);
+	else if(regnum>=(FIRST_CR+9)&&regnum<=(FIRST_CR+11))
+		retval=PT_CR_9+((regnum-(FIRST_CR+9))*CR_SIZE);
+	return(retval+blockend);
+}
+
+/*
+  WatchAreas are required if you put 2 or more watchpoints on the same address
+  or overlapping areas gdb will call us to delete the watchpoint more than
+  once when we try to delete them.
+  I attempted reference counting to reduce the number of areas unfortunately
+  they didn't shrink when areas had to be split overlapping occurs. 
+ */
+struct WatchArea;
+typedef struct WatchArea WatchArea;
+struct WatchArea
+{
+	WatchArea *Next;
+	CORE_ADDR LoAddr;
+	CORE_ADDR HiAddr;
+};
+
+static WatchArea *watchBase=NULL;
+int    watchAreaCnt=0;
+static CORE_ADDR watchLoAddr,watchHiAddr;
+
+
+
+CORE_ADDR
+s390_stopped_by_watchpoint (int pid)
+{
+	per_lowcore_bits per_lowcore;
+	ptrace_area parea;
+
+	parea.len=sizeof(per_lowcore);
+	parea.process_addr=(addr_t)&per_lowcore;
+	parea.kernel_addr=pt_off(per_info.lowcore);
+	ptrace(PTRACE_PEEKUSR_AREA,pid,&parea);
+	return (((per_lowcore.perc_storage_alteration==1)&&
+		 (per_lowcore.perc_store_real_address==0))
+		 ? TRUE:FALSE);
+}
+
+
+void s390_FixWatchPoints(int pid)
+{
+	per_struct per_info;
+	ptrace_area parea;
+
+	parea.len=sizeof(per_info);
+	parea.process_addr=(addr_t)&per_info;
+	parea.kernel_addr=PT_CR_9;
+	ptrace(PTRACE_PEEKUSR_AREA,pid,&parea);
+	/* The kernel automatically sets the psw for per depending */
+	/* on whether the per control registers are set for event recording */
+	/* & sets cr9 & cr10 appropriately also */
+	if(watchAreaCnt)
+	{
+		per_info.control_regs.bits.em_storage_alteration=1;
+		per_info.control_regs.bits.storage_alt_space_ctl=1;
+		per_info.starting_addr=watchLoAddr;
+		per_info.ending_addr=watchHiAddr;
+	}
+	else
+	{
+		per_info.control_regs.bits.em_storage_alteration=0;
+		per_info.control_regs.bits.storage_alt_space_ctl=0;
+	}
+	ptrace(PTRACE_POKEUSR_AREA,pid,&parea);
+}
+
+int
+s390_insert_watchpoint(int pid,CORE_ADDR addr,int len,int rw)
+{
+	CORE_ADDR hiAddr=addr+len-1;
+	WatchArea *newArea=(WatchArea *)malloc(sizeof(WatchArea));
+
+
+	if(newArea)
+	{
+		newArea->Next=watchBase;
+		watchBase=newArea;
+		watchLoAddr=min(watchLoAddr,addr);
+		watchHiAddr=max(watchHiAddr,hiAddr);
+		newArea->LoAddr=addr;
+		newArea->HiAddr=hiAddr;
+		watchAreaCnt++;
+		s390_FixWatchPoints(pid);
+	}
+	return(newArea ? 0:-1);
+}
+
+
+int
+s390_remove_watchpoint (int pid,CORE_ADDR addr,int len)
+{
+	WatchArea *curr=watchBase,*prev,*matchCurr;
+	CORE_ADDR hiAddr=addr+len-1;
+	CORE_ADDR watchSecondLoAddr=0xffffffffUL,watchSecondHiAddr=0;
+	int loAddrRefCnt,hiAddrRefCnt;
+	prev=matchCurr=NULL;
+	loAddrRefCnt=(addr==watchLoAddr);
+	hiAddrRefCnt=(addr==watchHiAddr);
+	while(curr)
+	{
+		if(matchCurr==NULL)
+		{
+			if(curr->LoAddr==addr&&curr->HiAddr==hiAddr)
+			{
+				matchCurr=curr;
+				if(prev)
+					prev->Next=curr->Next;
+				else
+					watchBase=curr->Next;
+			}
+			prev=curr;
+		}
+		if(loAddrRefCnt)
+		{
+			if(watchLoAddr==curr->LoAddr)
+				loAddrRefCnt++;
+			if(curr->LoAddr>watchLoAddr&&
+			   curr->LoAddr<watchSecondLoAddr)
+				watchSecondLoAddr=curr->LoAddr;
+		}
+		if(hiAddrRefCnt)
+		{
+			if(watchHiAddr==curr->HiAddr)
+				hiAddrRefCnt++;
+			if(curr->HiAddr<watchHiAddr&&
+			   curr->HiAddr>watchSecondHiAddr)
+				watchSecondHiAddr=curr->HiAddr;
+		}
+		curr=curr->Next;
+	}
+	if(matchCurr)
+	{
+		free(matchCurr);
+		watchAreaCnt--;
+		if(watchAreaCnt)
+		{
+			if(loAddrRefCnt==2)
+				watchLoAddr=watchSecondLoAddr;
+			if(hiAddrRefCnt==2)
+				watchHiAddr=watchSecondHiAddr;
+		}
+		s390_FixWatchPoints(pid);
+		return(0);
+	}
+	else
+	{
+		fprintf_unfiltered (gdb_stderr, "Attempt to remove nonexistent watchpoint in s390_remove_watchpoint\n"); 
+		return(-1);
+	}
+}
+
+#if  (defined (FP0_REGNUM) && defined (HAVE_FPREGSET_T) && defined(HAVE_SYS_PROCFS_H) && defined (HAVE_GREGSET_T))
+void supply_gregset (gregset_t *gregsetp)
+{
+    int regi;
+
+    for (regi = 0 ; regi <NUM_GPRS; regi++)
+	    supply_register (GP0_REGNUM+regi,&gregsetp->gprs[regi]);
+    supply_register (PSWM_REGNUM,&gregsetp->psw.mask);
+    supply_register (PC_REGNUM,&gregsetp->psw.addr);
+    for (regi = 0 ; regi <NUM_ACRS; regi++)
+	    supply_register(FIRST_ACR+regi,&gregsetp->acrs[regi]);
+    /* unfortunately this isn't in gregsetp */
+    for (regi = 0 ; regi <NUM_CRS; regi++)
+	    supply_register(FIRST_CR+regi,NULL);
+}
+
+
+void supply_fpregset (fpregset_t *fpregsetp)
+{
+	int regi;
+
+	supply_register(FPC_REGNUM,fpregsetp->fpc);
+	for (regi = 0 ; regi <NUM_FPRS; regi++)
+		supply_register(FP0_REGNUM+regi,&fpregsetp->fprs[regi]);
+	
+}
+#else
+#error "There are a few possibilities here"
+#error "1) You aren't compiling for linux & don't need a core dumps to work."
+#error "2) The header files sys/elf.h sys/user.h sys/ptrace.h & sys/procfs.h"
+#error "libc files are inconsistent with linux/include/asm-s390/"
+#error "3) you didn't do a completely clean build & delete config.cache."
+#endif
+
diff -u -r --new-file gdb-5.0/gdb/s390-tdep.c gdb-5.0-s390/gdb/s390-tdep.c
--- gdb-5.0/gdb/s390-tdep.c	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/gdb/s390-tdep.c	Tue Jul 18 19:16:40 2000
@@ -0,0 +1,922 @@
+/* Target-dependent code for GDB, the GNU debugger.
+   Copyright 1999 Free Software Foundation, Inc.
+   Ported by D.J. Barrow for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+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 "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include <asm/types.h>
+#include <asm/sigcontext.h>
+#include <asm/unistd.h>
+
+#define TDEP_DEBUG  0
+      
+#if TDEP_DEBUG
+#define tdep_printf  printf
+#else
+#define tdep_printf(noargs...)
+#endif
+
+void _initialize_s390_tdep PARAMS ((void));
+
+static CORE_ADDR
+s390_frame_saved_pc_nofix(struct frame_info *fi);
+
+CORE_ADDR s390_function_start(struct frame_info *fi)
+{
+	CORE_ADDR function_start=0;
+	
+	if(fi->extra_info&&fi->extra_info->initialised)
+		function_start=fi->extra_info->function_start;
+	else if(fi->pc)
+		function_start=get_pc_function_start(fi->pc);
+#if TDEP_DEBUG
+	if(function_start==0)
+		tdep_printf("Warning s390_function_start=0\n");
+#endif
+	return(function_start);
+}
+
+void memset_extra_info(struct frame_extra_info *fextra_info)
+{
+	memset(fextra_info,0,sizeof(struct frame_extra_info));
+}
+
+static int s390_is_sigreturn(CORE_ADDR pc,struct frame_info *sighandler_fi,
+			     sigregs **sregs,CORE_ADDR *sigcaller_pc)
+{
+	__u8     instr[S390_MAX_INSTR_SIZE];
+	disassemble_info info;
+	int      instrlen;
+	struct sigcontext *scontext=NULL;
+	int retval=FALSE;
+	CORE_ADDR orig_sp;
+	sigregs   *temp_sregs=NULL;
+	
+
+	info.read_memory_func=dis_asm_read_memory;
+	instrlen=s390_readinstruction(instr,pc,&info);
+	if(sigcaller_pc)
+		*sigcaller_pc=0;
+	if((instrlen==S390_SYSCALL_SIZE)&&
+	   (((S390_SYSCALL_OPCODE|__NR_sigreturn)==*(__u16 *)instr)||
+	    ((S390_SYSCALL_OPCODE|__NR_rt_sigreturn)==*(__u16 *)instr)))
+	{
+		if(sighandler_fi)
+		{
+			if(s390_frameless_function_invocation(sighandler_fi))
+				orig_sp=sighandler_fi->frame;
+			else
+				orig_sp=ADDR_BITS_REMOVE(
+				(CORE_ADDR)read_memory_integer(
+					sighandler_fi->frame,GPR_SIZE));
+			if(orig_sp&&sigcaller_pc)
+			{
+				scontext=(struct sigcontext *)(orig_sp+__SIGNAL_FRAMESIZE);
+				temp_sregs=(sigregs *)ADDR_BITS_REMOVE(
+					(CORE_ADDR)read_memory_integer(
+						(CORE_ADDR)&scontext->sregs,sizeof(CORE_ADDR)));
+				*sigcaller_pc=
+					ADDR_BITS_REMOVE(
+						(CORE_ADDR)read_memory_integer(
+							(CORE_ADDR)&temp_sregs->
+							regs.psw.addr,sizeof(CORE_ADDR)));
+			}
+		}
+		retval=TRUE;
+	}
+	if(sregs)
+		*sregs=temp_sregs;
+	return(retval);
+}
+
+/*
+  We need to do something better here but this will keep us out of trouble
+  for the moment.
+  For some reason the blockframe.c calls us with fi->next->fromleaf
+  so this seems of little use to us.
+ */
+void s390_init_frame_pc_first(int next_fromleaf,struct frame_info *fi)
+{
+	CORE_ADDR sigcaller_pc;
+
+	fi->pc=0;
+	if(next_fromleaf)
+	{
+		fi->pc=ADDR_BITS_REMOVE(read_register(RETADDR_REGNUM));
+		/* fix signal handlers */
+	}
+	else if(fi->next&&fi->next->pc)
+		fi->pc=s390_frame_saved_pc_nofix(fi->next);
+	if(fi->pc&&fi->next&&fi->next->frame&&s390_is_sigreturn(fi->pc,fi->next,
+								NULL,&sigcaller_pc))
+	{
+		fi->pc=sigcaller_pc;
+	}
+		
+}
+
+void s390_init_extra_frame_info(int fromleaf,struct frame_info *fi)
+{
+	fi->extra_info = frame_obstack_alloc (sizeof (struct frame_extra_info));
+	if(fi->pc)
+		s390_skip_prologue(get_pc_function_start(fi->pc),fi->extra_info,NULL,TRUE);
+	else
+		memset_extra_info(fi->extra_info);
+}
+
+/* If saved registers of frame FI are not known yet, read and cache them.
+   &FEXTRA_INFOP contains struct frame_extra_info; TDATAP can be NULL,
+   in which case the framedata are read.  */
+
+void s390_frame_get_saved_regs(struct frame_info *fi)
+{
+
+	if(fi->saved_regs==NULL)
+	{
+		
+		frame_saved_regs_zalloc (fi);
+		if(fi->extra_info)
+		{
+			if(!fi->extra_info->initialised&&fi->pc)
+				s390_skip_prologue(get_pc_function_start(fi->pc),fi->extra_info,fi,TRUE);
+			if(fi->extra_info->good_prologue)
+				s390_skip_prologue(fi->extra_info->function_start,fi->extra_info,fi,FALSE);
+		}
+#if TDEP_DEBUG
+		else
+			tdep_printf("bad call to s390_frame_get_saved_regs\n");
+#endif
+	}
+}
+
+
+
+CORE_ADDR
+s390_frame_args_address (struct frame_info *fi)
+{
+
+	/* Apparently gdb already knows gdb_args_offset itself */
+	return(fi->frame);
+}
+
+
+static CORE_ADDR
+s390_frame_saved_pc_nofix(struct frame_info *fi)
+{
+	tdep_printf("s390_frame_saved_pc %p\n",fi);
+
+	if(fi->extra_info&&fi->extra_info->saved_pc_valid)
+		return(fi->extra_info->saved_pc);
+	s390_frame_get_saved_regs(fi);
+	if(fi->extra_info)
+	{
+		fi->extra_info->saved_pc_valid=TRUE;
+		if(fi->extra_info->good_prologue)
+		{
+			return((fi->extra_info->saved_pc=ADDR_BITS_REMOVE(read_memory_integer(
+			fi->saved_regs[RETADDR_REGNUM],GPR_SIZE))));
+		}
+	}
+	return(0);
+}
+
+CORE_ADDR
+s390_frame_saved_pc(struct frame_info *fi)
+{
+	CORE_ADDR saved_pc=0,sig_pc;
+
+	if(fi->extra_info&&fi->extra_info->sig_fixed_saved_pc_valid)
+		 return(fi->extra_info->sig_fixed_saved_pc);
+	saved_pc=s390_frame_saved_pc_nofix(fi);
+
+	if(fi->extra_info)
+	{
+		fi->extra_info->sig_fixed_saved_pc_valid=TRUE;
+		if(saved_pc)
+		{
+			if(s390_is_sigreturn(saved_pc,fi,NULL,&sig_pc))
+				saved_pc=sig_pc;
+		}
+		fi->extra_info->sig_fixed_saved_pc=saved_pc;
+	}
+	return(saved_pc);
+}
+
+
+
+
+/* We want backtraces out of signal handlers so we don't
+   set thisframe->signal_handler_caller to 1 */
+
+CORE_ADDR
+s390_frame_chain (struct frame_info *thisframe)
+{
+	
+	CORE_ADDR prev_fp=0;
+	struct frame_extra_info fextra_info;
+	CORE_ADDR saved_pc,sig_pc;
+	int regno;
+	sigregs *sregs;
+	int      sigreturn;
+
+	if(thisframe->prev&&thisframe->prev->frame)
+	    prev_fp=thisframe->prev->frame;
+	else
+	{
+		/* We have to do some work */
+		if(!thisframe->pc)
+			return(0);
+		saved_pc=s390_frame_saved_pc_nofix(thisframe);		
+		if(!saved_pc)
+			return(0);
+		if((sigreturn=s390_is_sigreturn(saved_pc,thisframe,&sregs,&sig_pc)))
+			saved_pc=sig_pc;
+		s390_skip_prologue(get_pc_function_start(saved_pc),&fextra_info,NULL,TRUE);
+		if(!fextra_info.good_prologue)
+			return(0);
+		if(sigreturn)
+			prev_fp=ADDR_BITS_REMOVE((CORE_ADDR)read_memory_integer(
+				(CORE_ADDR)&sregs->regs.gprs[fextra_info.has_frame_pointer 
+								   ? 11:15],GPR_SIZE));
+		else
+		{
+			regno=(fextra_info.has_frame_pointer ? FRAME_REGNUM:SP_REGNUM);
+			/* if it wasn't saved we must be in the innermost frame */
+			prev_fp=ADDR_BITS_REMOVE(thisframe->saved_regs[regno] ?
+						 read_memory_integer(thisframe->saved_regs[regno],GPR_SIZE):
+						 read_register(regno));
+		}
+
+	
+	}
+	tdep_printf("s390_frame_chain %p prev_fp=%p\n",thisframe,prev_fp);
+	return(prev_fp);
+}
+
+/*
+  Whether struct frame_extra_info is actually needed I'll have to figure
+  out as our frames are similar to rs6000 there is a possibility
+  i386 dosen't need it.
+ */
+
+
+int s390_readinstruction(__u8 instr[],CORE_ADDR at,struct disassemble_info *info)
+{
+       int instrlen;
+
+       static int s390_instrlen[]=
+       {
+	 2,
+	 4,
+	 4,
+	 6
+       };
+      if((*info->read_memory_func)(at, &instr[0],2,info))
+        return(-1);
+      instrlen=s390_instrlen[instr[0]>>6];
+      if((*info->read_memory_func)(at+2, &instr[2],instrlen-2,info))
+	return(-1);
+      return(instrlen);
+}
+
+
+/* s390_skip_prologue based on Hartmuts
+   prologue definition in
+   gcc-2.8.1/config/l390/linux.c 
+
+   It reads one instruction at a time & based on whether
+   it looks like prologue code or not it makes a decision on
+   whether the prologue is over, there are various state machines
+   in the code to determine if the prologue code is possilby valid.
+   
+   This is done to hopefully allow the code survive minor revs of
+   calling conventions.
+
+  fextra_info must be already set up to come in with saved_regs not NULL
+*/
+
+CORE_ADDR s390_skip_prologue(CORE_ADDR pc,struct frame_extra_info *fextra_info,struct frame_info *fi,int init_extra_info)
+{
+#define CONST_POOL_REGIDX 13
+#define GOT_REGIDX        12
+	__u8     instr[S390_MAX_INSTR_SIZE];
+	CORE_ADDR test_pc=pc,test_pc2;
+	CORE_ADDR orig_sp,save_reg_addr,*saved_regs=NULL;
+	int valid_prologue,good_prologue=TRUE;
+	int gprs_saved[NUM_GPRS];
+	int fprs_saved[NUM_FPRS];
+	int regidx,instrlen;
+	int save_link_regidx,subtract_sp_regidx;
+	int const_pool_state,save_link_state,got_state;
+	int frame_pointer_found,varargs_found;
+	int loop_cnt,gdb_gpr_store,gdb_fpr_store;
+	int frame_pointer_regidx=0xf;
+	int offset;
+	disassemble_info info;
+	const_pool_state=save_link_state=got_state=0;
+	frame_pointer_found=varargs_found=FALSE;	
+	memset(gprs_saved,0,sizeof(gprs_saved));
+	memset(fprs_saved,0,sizeof(fprs_saved));
+	info.read_memory_func=dis_asm_read_memory;
+
+	if(fi)
+	{
+		saved_regs=fi->saved_regs;
+		orig_sp=fi->frame+fextra_info->stack_bought;
+	}
+	if(fextra_info)
+	{
+		if(init_extra_info||fextra_info->initialised==FALSE)
+		{
+			memset_extra_info(fextra_info);
+			fextra_info->function_start=pc;
+			fextra_info->initialised=TRUE;
+		}
+	}
+	instrlen=0;
+	do
+	{
+		valid_prologue=FALSE;
+		test_pc+=instrlen; 
+                /* add the previous instruction len */
+		instrlen=s390_readinstruction(instr,test_pc,&info);
+		if(instrlen<0)
+		{
+			good_prologue=FALSE;
+			break;
+		}
+		if(save_link_state==0)
+		{
+			/* check for  a stack relative STM */
+			if(instr[0]==0x90&&((instr[2]>>4)==0xf))
+			{
+				regidx=(instr[1]>>4);
+				if(regidx<6)
+					break;
+				if(saved_regs)
+					save_reg_addr=orig_sp+((*((__u16 *)&instr[2]))&0xfff);
+				for(;regidx<=(instr[1]&0xf);regidx++)
+				{
+					if(gprs_saved[regidx])
+					{
+						good_prologue=FALSE;
+						break;
+					}
+					
+					gprs_saved[regidx]=TRUE;
+					if(saved_regs)
+					{
+						saved_regs[GP0_REGNUM+regidx]=save_reg_addr;
+						save_reg_addr+=GPR_SIZE;
+					}
+				}	
+				valid_prologue=TRUE;
+				continue;
+			}
+			/* check for an ST */
+			if(instr[0]==0x50&&(instr[2]>>4)==0xf)
+			{
+				regidx=instr[1]>>4;
+				if(regidx<6)
+					break;
+				if(gprs_saved[regidx])
+				{
+					good_prologue=FALSE;
+					break;
+				}
+				gprs_saved[regidx]=TRUE;
+				if(saved_regs)
+				{
+					save_reg_addr=orig_sp+((*((__u16 *)&instr[2]))&0xfff);
+					saved_regs[GP0_REGNUM+regidx]=save_reg_addr;
+				}
+				valid_prologue=TRUE;
+				continue;
+			}
+
+			/* check for STD */
+			if(instr[0]==0x60&&(instr[2]>>4)==0xf)
+			{
+				regidx=instr[1]>>4;
+				if(regidx==0||regidx==2)
+					break;
+				if(fprs_saved[regidx])
+				{
+					good_prologue=FALSE;
+					break;
+				}
+				fprs_saved[regidx]=TRUE;
+				if(saved_regs)
+				{
+					save_reg_addr=orig_sp+((*((__u16 *)&instr[2]))&0xfff);
+					saved_regs[FP0_REGNUM+regidx]=save_reg_addr;
+				}
+				valid_prologue=TRUE;
+				continue;
+			}
+		}
+		
+		if(const_pool_state==0)
+		{
+			/* Check for BASR gpr13,gpr0 used to load constant pool pointer to r13 in old compiler*/
+			if(instr[0]==0xd&&(instr[1]&0xf)==0&&((instr[1]>>4)==CONST_POOL_REGIDX))
+			{
+				const_pool_state=1;
+				valid_prologue=TRUE;
+				continue;
+			}
+			/* Check for new fangled bras %r13,newpc to load new constant pool */
+			/* embedded in code */
+			if((instr[0]==0xa7)&&((instr[1]&0xf)==0x5)&&
+			   ((instr[1]>>4)==CONST_POOL_REGIDX)&&((instr[2]&0x80)==0))
+			{
+				const_pool_state=2;
+				test_pc+=((*((__u16 *)&instr[2])<<1)-instrlen);
+				valid_prologue=TRUE;
+				continue;
+			}
+		}
+		/* Check for AHI basr_regidx,val */
+		if(const_pool_state==1&&(instr[0]==0xa7)&&
+		   ((instr[1]&0xf)==0xa)&&((instr[1]>>4)==CONST_POOL_REGIDX))
+		{
+			const_pool_state=2;
+			valid_prologue=TRUE;
+			continue;
+		}
+		/* Check for LR gprx,15 */ 
+		if(instr[0]==0x18&&(instr[1]&0xf)==0xf)
+		{
+			regidx=instr[1]>>4;
+			if(save_link_state==0&&regidx!=0xb)
+			{
+				/* Almost defintely code for
+				  decrementing the stack pointer 
+				  ( i.e. a non leaf function 
+				  or else leaf with locals ) */
+				save_link_regidx=instr[1]>>4;
+				save_link_state=1;
+				valid_prologue=TRUE;
+				continue;
+			}
+			/*
+			  We use this frame pointer for alloca
+			  unfortunately we need to assume its gpr11
+			  otherwise we would need a smarter prologue
+			  walker
+			 */
+			if(frame_pointer_found==FALSE&&regidx==0xb)
+			{
+				frame_pointer_regidx=0xb;
+				frame_pointer_found=TRUE;
+				if(fextra_info)
+					fextra_info->has_frame_pointer=TRUE;	
+				valid_prologue=TRUE;
+				continue;
+			}
+		}
+	        /* Check for AHI gpr15,val */
+		if(save_link_state==1&&(instr[0]==0xa7)&&(instr[1]==0xfa))
+		{
+			if(fextra_info)
+				fextra_info->stack_bought=-(*((__s16 *)&instr[2]));
+			save_link_state=3;
+			valid_prologue=TRUE;
+			continue;
+		}
+		/* Alternatively check for the complex construction for
+		 buying more than 32k of stack
+		 BRAS gprx,.+8
+		 long val
+		 s    %r15,0(%gprx)  gprx currently r1
+		*/
+		if(save_link_state==1&&(instr[0]==0xa7)&&(instr[1]&0xf==0x5)
+		   &&(*((__u16 *)&instr[2])==0x4)&&((instr[1]>>4)!=CONST_POOL_REGIDX))
+		{
+			subtract_sp_regidx=instr[1]>>4;
+			save_link_state=2;
+			if(fextra_info)
+			       target_read_memory (test_pc,
+						   (char *)&fextra_info->stack_bought,
+						   sizeof(fextra_info->stack_bought));
+			test_pc+=4;
+			valid_prologue=TRUE;
+			continue;
+		}
+		if(save_link_state==2&&(*((__u16 *)&instr[0])==0x5bf0)&&
+		   (*((__u16 *)&instr[2])==subtract_sp_regidx<<12))
+		{
+			save_link_state=3;
+			valid_prologue=TRUE;
+			continue;
+		}
+		/* Check for store ST save_link_regidx,0(15) */
+		/* New stack pointer */
+		if(save_link_state==3&&instr[0]==0x50
+		   &&(instr[1]==(save_link_regidx<<4))
+		   &&(*((__u16 *)&instr[2])==0xf000))
+		{
+			save_link_state=4;
+			valid_prologue=TRUE;
+			continue;
+		}
+		/* check for LA gprx,offset(15)
+		   used for varargs
+		 */
+		if(varargs_found==FALSE&&
+		   instr[0]==0x41&&((instr[1]&0xf)==0)
+		   &&((instr[2]>>4)==0xf))
+		{
+			varargs_found=TRUE;
+			valid_prologue=TRUE;
+			continue;
+		}
+		/*
+		  Check for a GOT load
+		  we might be able to get info like whether we
+		  are compiled -fpic to check whether this is valid
+		  prologue
+		 */
+		if(got_state==0&&const_pool_state==2&&instr[0]==0x58
+		   &&(instr[2]==(CONST_POOL_REGIDX<<4))&&((instr[1]>>4)==GOT_REGIDX))
+		   {
+			   got_state==1;
+			   valid_prologue=TRUE;
+			   continue;
+		   }
+		/*
+		  Check for subsequent ar got_regidx,basr_regidx
+		 */
+		if(got_state==1&&instr[0]==0x1a&&
+		   instr[1]==((GOT_REGIDX<<4)|CONST_POOL_REGIDX))
+		{
+			got_state=2;
+			valid_prologue=TRUE;
+			continue;
+		}
+	}while(valid_prologue);
+	if(good_prologue==TRUE)
+	{
+		good_prologue=(((got_state==0)||(got_state==2))&&
+		((const_pool_state==0)||(const_pool_state==2))&&
+	        ((save_link_state==0)||(save_link_state==4)));
+	}
+#if 0
+	tdep_printf("s390_skip_prologue pc=%p,test_pc=%p good_prol=%d fextra_info=%p\n",
+	       pc,test_pc,good_prologue,fextra_info);
+        /*
+          Sniff to see if gcc was kind enough to save our
+	  parameters on the stack.
+        */
+	if(fextra_info)
+	{
+		test_pc2=test_pc;
+		gdb_gpr_store=gdb_fpr_store=FALSE;
+		for(loop_cnt=0;loop_cnt<10;loop_cnt++)
+		{
+			if(loop_cnt)
+			{
+				instrlen=s390_readinstruction(instr,test_pc2,&info);
+				if(instrlen<0)
+					break;
+				test_pc2+=instrlen;
+			}
+			/* Check for ST gpr2,x(15) */
+			if((instr[0]==0x50&&(instr[2]>>4)==frame_pointer_regidx&&
+			    (instr[1]>>4)==2)&&gdb_gpr_store==FALSE)
+			{
+				fextra_info->gdb_args_offset=min(fextra_info->gdb_args_offset,
+							   *((__u16 *)&instr[2])&0xfff);
+				gdb_gpr_store=TRUE;
+			}
+	
+			/* Check for an STD/STE fpr0,x(15) */
+			if((instr[0]==0x70||instr[0]==0x60)&&
+			   ((instr[2]>>4)==frame_pointer_regidx)&&
+			   (instr[1]>>4)==0&&gdb_fpr_store==FALSE)
+			{
+				fextra_info->gdb_args_offset=min(fextra_info->gdb_args_offset,
+							   *((__u16 *)&instr[2])&0xfff);
+				gdb_fpr_store=TRUE;
+				
+			}
+			/* stack relative load */ 
+			if(instr[0]==0x58&&(instr[2]>>4)==0xf)
+				break;
+			/* stack relative load multiple */
+			if(instr[0]==0x98&&(instr[2]>>4)==0xf)
+				break;
+			/* branch possibly 07fe == return */
+			if(instr[0]==0x7)
+				break;
+		}
+ 	  }
+#endif
+	if(fextra_info)
+		fextra_info->good_prologue=good_prologue;
+	return(good_prologue ? test_pc:pc);
+}
+
+/* a given return value in `regbuf' with a type `valtype', extract and copy its
+   value into `valbuf' */
+
+void
+s390_extract_return_value (struct type *valtype,char regbuf[REGISTER_BYTES],char *valbuf)
+{
+	int offset = 0;
+	double dd; float ff;
+	/* floats and doubles are returned in fpr0. fpr's have a size of 8 bytes.
+	   We need to truncate the return value into float size (4 byte) if
+	   necessary. */
+
+	if (TYPE_CODE (valtype) == TYPE_CODE_FLT) 
+	{
+		if (TYPE_LENGTH (valtype) > sizeof(float)) 	/* this is a double */
+			memcpy (valbuf, 
+				&regbuf[REGISTER_BYTE (FP0_REGNUM)],
+				TYPE_LENGTH (valtype));
+		else 
+		{		/* float */
+			memcpy (&dd, &regbuf[REGISTER_BYTE (FP0_REGNUM)], FPR_SIZE);
+			ff = (float)dd;
+			memcpy (valbuf, &ff, sizeof(float));
+		}
+	}
+	else 
+	{
+		/* return value is copied starting from r2. */
+		if (TYPE_LENGTH (valtype) < GPR_SIZE )
+			offset = GPR_SIZE - TYPE_LENGTH (valtype);
+		memcpy (valbuf, 
+			regbuf + REGISTER_BYTE (GP0_REGNUM+2) + offset,
+			TYPE_LENGTH (valtype));
+	}
+}
+
+
+
+
+void s390_store_return_value (struct type *valtype, char *valbuf)
+{
+	double ret_double;
+
+	if (TYPE_CODE (valtype) == TYPE_CODE_FLT)				
+	{	
+		if (TYPE_LENGTH(valtype)==sizeof(float))
+			ret_double=(double)(*((float *)valbuf));
+		write_register_bytes(REGISTER_BYTE (FP0_REGNUM),
+				      (TYPE_LENGTH(valtype)==sizeof(float) ? (char *)&ret_double:valbuf),
+				      FPR_SIZE);
+	}
+	else								
+		/* Everything else is returned in GPR2 and up. */			
+		write_register_bytes (REGISTER_BYTE (GP0_REGNUM+2), (valbuf),	
+				      TYPE_LENGTH (valtype));	
+}
+static int
+gdb_print_insn_s390 (bfd_vma memaddr,disassemble_info * info)
+{
+	__u8 instrbuff[S390_MAX_INSTR_SIZE];
+	int instrlen,cnt;
+
+	instrlen=s390_readinstruction(instrbuff,(CORE_ADDR)memaddr,info);
+       	if (instrlen<0) {
+		(*info->memory_error_func) (instrlen, memaddr, info);
+		return -1;
+	}
+	for(cnt=0;cnt<instrlen;cnt++)
+		info->fprintf_func(info->stream,"%02X ",instrbuff[cnt]);
+	for(cnt=instrlen;cnt<S390_MAX_INSTR_SIZE;cnt++)
+		info->fprintf_func(info->stream,"   ");
+	instrlen=print_insn_s390(memaddr,info);
+	return(instrlen);
+}
+
+void
+_initialize_s390_tdep ()
+{
+	const bfd_arch_info_type *s390_arch_ptr=bfd_lookup_arch (bfd_arch_s390, 0);
+	tm_print_insn =  gdb_print_insn_s390;
+	
+	if(s390_arch_ptr)
+		tm_print_insn_info.mach = s390_arch_ptr->mach;
+	else
+		internal_error ("initialize_s390_tdep: bld_lookup_arch failed for bfd_arch_s390 recompile.\n");
+}
+
+
+/* Not the most efficent code in the world */
+int s390_fp_regnum()
+{
+	int regno=SP_REGNUM;
+	struct frame_extra_info fextra_info;
+	s390_skip_prologue(get_pc_function_start (read_register (PC_REGNUM)),&fextra_info,NULL,TRUE);
+	if(fextra_info.good_prologue&&fextra_info.has_frame_pointer)
+		regno=FRAME_REGNUM;
+	return(regno);
+}
+
+CORE_ADDR s390_read_fp()
+{
+	return(read_register(s390_fp_regnum())); 
+}
+
+
+void s390_write_fp(CORE_ADDR val)
+{
+	write_register(s390_fp_regnum(),val);
+}
+
+
+
+int s390_frameless_function_invocation(struct frame_info *fi)
+{
+	struct frame_extra_info fextra_info,*fextra_info_ptr;
+	int    frameless=0;
+
+	if(fi->next==NULL) /* no may be frameless */
+	{
+		if(fi->extra_info)
+			fextra_info_ptr=fi->extra_info;
+		else
+		{
+			fextra_info_ptr=&fextra_info;
+			s390_skip_prologue(get_pc_function_start(fi->pc),fextra_info_ptr,NULL,TRUE);
+		}
+		frameless=((fextra_info_ptr->good_prologue)&&(fextra_info_ptr->stack_bought==0));
+	}
+	tdep_printf("s390_frameless_function_invocation fi=%p fi->pc=%p frameless=%d\n",fi,fi->pc,frameless);
+	return(frameless);
+
+}
+
+void s390_push_dummy_frame()
+{
+	CORE_ADDR orig_sp=read_register(SP_REGNUM),new_sp;
+	s390_gdb_regs saved_regs;
+	
+	new_sp=(orig_sp-(sizeof(s390_gdb_regs)+sizeof(CORE_ADDR)));
+	read_register_bytes(0,(char *)&saved_regs,sizeof(saved_regs));
+	write_memory(new_sp,(char *)&orig_sp,GPR_SIZE);
+	write_memory(new_sp+GPR_SIZE,(char *)&saved_regs,sizeof(saved_regs));
+	write_register(SP_REGNUM,new_sp);
+	
+}
+
+/* pop the innermost frame, go back to the caller.
+    Used in `call_function_by_hand' to remove an artificial stack
+     frame.            
+*/
+void s390_pop_frame()
+{
+	CORE_ADDR new_sp=read_register(SP_REGNUM),orig_sp;
+	s390_gdb_regs saved_regs;
+
+	read_memory(new_sp+GPR_SIZE,(char *)&saved_regs,sizeof(saved_regs));
+	read_register_bytes(0,(char *)&saved_regs,sizeof(saved_regs));
+	orig_sp=read_memory_integer(new_sp,GPR_SIZE);
+	write_register(SP_REGNUM,orig_sp);
+	tdep_printf("s390_pop_frame orig_sp=%X\n",orig_sp);
+}
+
+/*
+  used by call function by hand
+  struct_return indicates that this function returns a structure &
+  therefore gpr2 stores a pointer to the structure to be returned as
+  opposed to the first argument.
+  Currently I haven't seen a TYPE_CODE_INT whose size wasn't 2^n or less
+  than GPR_SIZE this is good because I don't seem to have to worry
+  about sign extending pushed arguments (i.e. a signed char currently
+  comes into this code with a size of 4 ).
+ */
+CORE_ADDR
+s390_push_arguments(int nargs,value_ptr *args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)
+{
+	int num_float_args,num_gpr_args,orig_num_gpr_args,argno;
+	int second_pass,len,gprs_required;
+	CORE_ADDR outgoing_args_ptr,outgoing_args_space;
+	value_ptr arg;
+	struct type *type;
+	/*
+	  We need this constuct otherwise we will end up passing
+	  args to write_register in fpu registers.
+	 */
+	volatile union
+	{
+		double double_arg;
+		long long long_long_arg;
+	} u; 
+	int max_num_gpr_args=5-(struct_return ? 1:0);
+	int arg0_regnum=GP0_REGNUM+2+(struct_return ? 1:0);
+
+	for(second_pass=FALSE;second_pass<=TRUE;second_pass++)
+	{
+		if(second_pass)
+			outgoing_args_ptr=sp+96;
+		else
+			outgoing_args_ptr=0;
+		num_float_args=0;
+		num_gpr_args=0;
+		for(argno=0;argno<nargs;argno++)
+		{
+			arg = args[argno];
+			type = check_typedef (VALUE_TYPE (arg));
+			len = TYPE_LENGTH (type);
+			if(TYPE_CODE (type)==TYPE_CODE_FLT)
+			{
+			        if(num_float_args>1)
+				{
+					if(second_pass)
+						write_memory(outgoing_args_ptr,
+							     ((char*)VALUE_CONTENTS (arg)),len);  
+					outgoing_args_ptr+=len;
+				}
+				else if(second_pass)
+				{
+					if(len==sizeof(float))
+						u.double_arg=*((float *)VALUE_CONTENTS(arg));
+					else
+						u.long_long_arg=*(long long *)VALUE_CONTENTS(arg);
+					write_register(FP0_REGNUM+(2*num_float_args),u.long_long_arg);
+				}
+				num_float_args++;
+			}
+			else
+			{
+				gprs_required=((len+(GPR_SIZE-1))/GPR_SIZE);
+				/* if the check below prints an error check gdbtypes.h
+				 * & definitions of TYPE_CODE_INT TYPE_FLAG_SIGNED TYPE_FLAG_NOSIGN 
+				 * & do some debugging.
+				 */
+				if(len&(GPR_SIZE-1))
+					 fprintf_unfiltered (gdb_stderr,
+							     "gdb s390_push_arguments detected an argument not"
+							     "a multiple of GPR_SIZE in size we need to add"
+							     "check whether sign extension is needed FIXME.\n");
+				orig_num_gpr_args=num_gpr_args;
+				num_gpr_args+=gprs_required;
+				if(num_gpr_args>max_num_gpr_args)
+				{
+					if(second_pass)
+						write_memory(outgoing_args_ptr,
+							     ((char*)VALUE_CONTENTS(arg)),len);
+					outgoing_args_ptr+=len;
+				}
+				else
+				{
+					if(second_pass)
+						write_register_bytes(REGISTER_BYTE(arg0_regnum)
+								     +(orig_num_gpr_args*GPR_SIZE),
+								     VALUE_CONTENTS(arg),len);
+				}
+			}
+		}
+		if(!second_pass)
+		{
+			outgoing_args_space=outgoing_args_ptr;
+			/* Align to 16 bytes because because I like alignment & 
+			   some of the kernel code requires 8 byte stack alignment at least. */
+			sp=(sp-(STACK_FRAME_OVERHEAD+outgoing_args_ptr))&0xfffffff0;
+		}
+
+	}
+	return(sp);
+	
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -u -r --new-file gdb-5.0/include/dis-asm.h gdb-5.0-s390/include/dis-asm.h
--- gdb-5.0/include/dis-asm.h	Mon Mar 27 10:39:13 2000
+++ gdb-5.0-s390/include/dis-asm.h	Tue Jul 18 19:16:44 2000
@@ -158,6 +158,7 @@
 extern int print_insn_i386_att		PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_i386_intel	PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_i370		PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_s390		PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_m68k		PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_z8001		PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_z8002		PARAMS ((bfd_vma, disassemble_info*));
diff -u -r --new-file gdb-5.0/include/elf/common.h gdb-5.0-s390/include/elf/common.h
--- gdb-5.0/include/elf/common.h	Mon Mar 27 10:39:13 2000
+++ gdb-5.0-s390/include/elf/common.h	Tue Jul 18 19:16:45 2000
@@ -186,6 +186,9 @@
 #define EM_CYGNUS_MN10200	0xdead
 #define EM_CYGNUS_MN10300	0xbeef
 
+/* IBM S390 */
+#define EM_S390                       0xA390
+
 /* FR30 magic number - no EABI available.  */
 #define EM_CYGNUS_FR30		0x3330
 
diff -u -r --new-file gdb-5.0/include/elf/s390.h gdb-5.0-s390/include/elf/s390.h
--- gdb-5.0/include/elf/s390.h	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/include/elf/s390.h	Tue Jul 18 19:16:45 2000
@@ -0,0 +1,59 @@
+/* 390 ELF support for BFD.
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+   Contributed by Carl B. Pedersen and Martin Schwidefsky.
+
+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_390_H
+#define _ELF_390_H
+
+/* Processor specific flags for the ELF header e_flags field.  */
+
+/* Symbol types.  */
+
+#define STACK_REG		15		/* Global Stack reg */
+#define BACKL_REG		14		/* Global Backlink reg */
+#define BASE_REG		13		/* Global Base reg */
+#define GOT_REG 		12		/* Holds addr of GOT */
+
+/* Relocation types.  */
+
+enum elf_390_reloc_type {
+    R_390_NONE = 0,
+    R_390_8,
+    R_390_12,
+    R_390_16,
+    R_390_32,
+    R_390_PC32,
+    R_390_GOT12,
+    R_390_GOT32,
+    R_390_PLT32,
+    R_390_COPY,
+    R_390_GLOB_DAT, 
+    R_390_JMP_SLOT,
+    R_390_RELATIVE,
+    R_390_GOTOFF,
+    R_390_GOTPC,
+    R_390_GOT16,
+    R_390_PC16,
+    R_390_PC16DBL,
+    R_390_PLT16DBL,
+    R_390_max
+};
+
+#endif /* _ELF_390_H */
diff -u -r --new-file gdb-5.0/include/opcode/s390.h gdb-5.0-s390/include/opcode/s390.h
--- gdb-5.0/include/opcode/s390.h	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/include/opcode/s390.h	Tue Jul 18 19:16:45 2000
@@ -0,0 +1,115 @@
+/* s390.h -- Header file for S390 opcode table
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them under the terms of the GNU General Public
+License as published by the Free Software Foundation; either version
+1, or (at your option) any later version.
+
+GDB, GAS, and the 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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef S390_H
+#define S390_H
+
+/* The opcode table is an array of struct s390_opcode.  */
+
+struct s390_opcode
+{
+  /* The opcode name.  */
+  const char *name;
+
+  /* The opcode itself.  Those bits which will be filled in with
+     operands are zeroes.  */
+  unsigned char opcode[6];
+
+  /* The opcode mask.  This is used by the disassembler.  This is a
+     mask containing ones indicating those bits which must match the
+     opcode field, and zeroes indicating those bits which need not
+     match (and are presumably filled in by operands).  */
+  unsigned char mask[6];
+
+  /* The opcode length in bytes. */
+  int oplen;
+
+  /* An array of operand codes.  Each code is an index into the
+     operand table.  They appear in the order which the operands must
+     appear in assembly code, and are terminated by a zero.  */
+  unsigned char operands[6];
+};
+
+/* The table itself is sorted by major opcode number, and is otherwise
+   in the order in which the disassembler should consider
+   instructions.  */
+extern const struct s390_opcode s390_opcodes[];
+extern const int s390_num_opcodes;
+
+/* Values defined for the flags field of a struct powerpc_opcode.  */
+
+/* The operands table is an array of struct s390_operand.  */
+
+struct s390_operand
+{
+  /* The number of bits in the operand.  */
+  int bits;
+
+  /* How far the operand is left shifted in the instruction.  */
+  int shift;
+
+  /* One bit syntax flags.  */
+  unsigned long flags;
+};
+
+/* Elements in the table are retrieved by indexing with values from
+   the operands field of the powerpc_opcodes table.  */
+
+extern const struct s390_operand s390_operands[];
+
+/* Values defined for the flags field of a struct s390_operand.  */
+
+/* This operand names a register.  The disassembler uses this to print
+   register names with a leading 'r'.  */
+#define S390_OPERAND_GPR 0x1
+
+/* This operand names a floating point register.  The disassembler
+   prints these with a leading 'f'. */
+#define S390_OPERAND_FPR 0x2
+
+/* This operand names an access register.  The disassembler
+   prints these with a leading 'a'.  */
+#define S390_OPERAND_AR 0x4
+
+/* This operand names a control register.  The disassembler
+   prints these with a leading 'c'.  */
+#define S390_OPERAND_CR 0x8
+
+/* This operand is a displacement */
+#define S390_OPERAND_DISP 0x10
+
+/* This operand names a base register. */
+#define S390_OPERAND_BASE 0x20
+
+/* This operand names an index register, it can be skipped. */
+#define S390_OPERAND_INDEX 0x40
+
+/* This operand is a relative branch displacement.  The disassembler
+   prints these symbolically if possible.  */
+#define S390_OPERAND_PCREL 0x80
+
+/* This operand takes signed values.  */
+#define S390_OPERAND_SIGNED 0x100
+
+/* This operand is a length.  */
+#define S390_OPERAND_LENGTH 0x200
+
+#endif /* S390_H */
diff -u -r --new-file gdb-5.0/opcodes/Makefile.am gdb-5.0-s390/opcodes/Makefile.am
--- gdb-5.0/opcodes/Makefile.am	Sun Apr  9 14:17:43 2000
+++ gdb-5.0-s390/opcodes/Makefile.am	Fri Aug 18 14:41:17 2000
@@ -80,6 +80,7 @@
 	pj-opc.c \
 	ppc-dis.c \
 	ppc-opc.c \
+	s390-dis.c \
 	sh-dis.c \
 	sparc-dis.c \
 	sparc-opc.c \
@@ -142,6 +143,7 @@
 	ppc-dis.lo \
 	ppc-opc.lo \
 	ns32k-dis.lo \
+	s390-dis.lo \
 	sh-dis.lo \
 	sparc-dis.lo \
 	sparc-opc.lo \
@@ -358,6 +360,8 @@
   config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ppc.h
 ppc-opc.lo: ppc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/ppc.h \
   opintl.h
+s390-dis.lo: s390-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h sysdep.h config.h
 sh-dis.lo: sh-dis.c sh-opc.h $(INCDIR)/dis-asm.h $(BFD_H) \
   $(INCDIR)/ansidecl.h
 sparc-dis.lo: sparc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
diff -u -r --new-file gdb-5.0/opcodes/Makefile.in gdb-5.0-s390/opcodes/Makefile.in
--- gdb-5.0/opcodes/Makefile.in	Sun Apr  9 14:17:43 2000
+++ gdb-5.0-s390/opcodes/Makefile.in	Fri Aug 18 14:41:18 2000
@@ -184,6 +184,7 @@
 	pj-opc.c \
 	ppc-dis.c \
 	ppc-opc.c \
+	s390-dis.c \
 	sh-dis.c \
 	sparc-dis.c \
 	sparc-opc.c \
@@ -247,6 +248,7 @@
 	ppc-dis.lo \
 	ppc-opc.lo \
 	ns32k-dis.lo \
+	s390-dis.lo \
 	sh-dis.lo \
 	sparc-dis.lo \
 	sparc-opc.lo \
@@ -855,6 +857,8 @@
   config.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/opcode/ppc.h
 ppc-opc.lo: ppc-opc.c $(INCDIR)/ansidecl.h $(INCDIR)/opcode/ppc.h \
   opintl.h
+s390-dis.lo: s390-dis.c $(INCDIR)/dis-asm.h $(BFD_H) \
+  $(INCDIR)/ansidecl.h sysdep.h config.h
 sh-dis.lo: sh-dis.c sh-opc.h $(INCDIR)/dis-asm.h $(BFD_H) \
   $(INCDIR)/ansidecl.h
 sparc-dis.lo: sparc-dis.c $(INCDIR)/ansidecl.h sysdep.h \
diff -u -r --new-file gdb-5.0/opcodes/configure gdb-5.0-s390/opcodes/configure
--- gdb-5.0/opcodes/configure	Sun Apr  9 14:17:43 2000
+++ gdb-5.0-s390/opcodes/configure	Tue Jul 18 19:16:45 2000
@@ -3968,6 +3968,7 @@
 	bfd_pyramid_arch)	;;
 	bfd_romp_arch)		;;
 	bfd_rs6000_arch)	ta="$ta ppc-dis.lo ppc-opc.lo" ;;
+	bfd_s390_arch)          ta="$ta s390-dis.lo s390-opc.lo" ;;
 	bfd_sh_arch)		ta="$ta sh-dis.lo" ;;
 	bfd_sparc_arch)		ta="$ta sparc-dis.lo sparc-opc.lo" ;;
 	bfd_tahoe_arch)		;;
diff -u -r --new-file gdb-5.0/opcodes/disassemble.c gdb-5.0-s390/opcodes/disassemble.c
--- gdb-5.0/opcodes/disassemble.c	Sun Apr  2 08:26:09 2000
+++ gdb-5.0-s390/opcodes/disassemble.c	Tue Jul 18 19:16:45 2000
@@ -47,6 +47,7 @@
 #define ARCH_rs6000
 #define ARCH_sh
 #define ARCH_sparc
+#define ARCH_s390
 #define ARCH_tic30
 #define ARCH_tic80
 #define ARCH_v850
@@ -211,6 +212,11 @@
 #ifdef ARCH_rs6000
     case bfd_arch_rs6000:
       disassemble = print_insn_rs6000;
+      break;
+#endif
+#ifdef ARCH_s390
+    case bfd_arch_s390:
+      disassemble = print_insn_s390;
       break;
 #endif
 #ifdef ARCH_sh
diff -u -r --new-file gdb-5.0/opcodes/s390-dis.c gdb-5.0-s390/opcodes/s390-dis.c
--- gdb-5.0/opcodes/s390-dis.c	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/opcodes/s390-dis.c	Tue Jul 18 19:16:46 2000
@@ -0,0 +1,220 @@
+/* s390-dis.c -- Disassemble S390 instructions
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them 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, GAS, and the 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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "sysdep.h"
+#include "dis-asm.h"
+#include "opcode/s390.h"
+
+static int init_flag = 0;
+static int opc_index[256];
+
+/* Set up index table for first opcode byte */
+static void 
+init_disasm(info)
+    struct disassemble_info *info;
+{
+  const struct s390_opcode *opcode;
+  const struct s390_opcode *opcode_end;
+
+  memset(opc_index, 0, sizeof(opc_index));
+  opcode_end = s390_opcodes + s390_num_opcodes;
+  for (opcode = s390_opcodes; opcode < opcode_end; opcode++) {
+    opc_index[(int) opcode->opcode[0]] = opcode - s390_opcodes;
+    while ((opcode < opcode_end) && 
+           (opcode[1].opcode[0] == opcode->opcode[0]))
+      opcode++;
+  }
+  init_flag = 1;
+}
+
+/* Extracts an operand value from an instruction.  */
+
+static inline unsigned int
+s390_extract_operand (insn, operand)
+     unsigned char *insn;
+     const struct s390_operand *operand;
+{
+  unsigned int val;
+  int bits;
+
+  /* extract fragments of the operand byte for byte */
+  insn += operand->shift/8;
+  bits = (operand->shift & 7) + operand->bits;
+  val = 0;
+  do {
+    val <<= 8;
+    val |= (unsigned int) *insn++;
+    bits -= 8;
+  } while (bits > 0);
+  val >>= -bits;
+  val &= ((1U << (operand->bits-1))<<1) - 1;
+
+  /* sign extend value if the operand is signed or pc relative */
+  if (operand->flags & (S390_OPERAND_SIGNED|S390_OPERAND_PCREL))
+    val |= (-1U << (operand->bits-1))<<1;
+ 
+  /* double value if the operand is pc relative */
+  if (operand->flags & S390_OPERAND_PCREL)
+    val <<= 1;
+ 
+  /* length x in an instructions has real length x+1 */
+  if (operand->flags & S390_OPERAND_LENGTH)
+    val++;
+  return val;
+}
+
+/* Print a S390 instruction.  */
+
+int
+print_insn_s390 (memaddr, info)
+     bfd_vma memaddr;
+     struct disassemble_info *info;
+{
+  bfd_byte buffer[6];
+  const struct s390_opcode *opcode;
+  const struct s390_opcode *opcode_end;
+  unsigned int value;
+  int status, opsize, bufsize;
+  char separator;
+
+  if (init_flag == 0)
+    init_disasm(info);
+
+  /* The output looks better if we put 6 bytes on a line */
+  info->bytes_per_line = 6;
+
+  /* every S390 instruction is max 6 bytes long */
+  memset(buffer, 0, 6);
+  status = (*info->read_memory_func) (memaddr, buffer, 6, info);
+  if (status != 0) {
+    for (bufsize = 0; bufsize < 6; bufsize++)
+      if ((*info->read_memory_func) (memaddr, buffer, bufsize+1, info) != 0)
+        break;
+    if (bufsize <= 0) {
+      (*info->memory_error_func) (status, memaddr, info);
+      return -1;
+    }
+    /*
+     * opsize calculation looks strange but it works
+     * 00xxxxxx -> 2 bytes, 01xxxxxx/10xxxxxx -> 4 bytes, 11xxxxxx -> 6 bytes
+     */
+    opsize = ((((buffer[0]>>6)+1)>>1)+1)<<1;
+    status = opsize > bufsize;
+  } else {
+    bufsize = 6;
+    opsize = ((((buffer[0]>>6)+1)>>1)+1)<<1;
+  }
+
+  if (status == 0) {
+    /* find the first match in the opcode table */
+    opcode_end = s390_opcodes + s390_num_opcodes;
+    for (opcode = s390_opcodes + opc_index[(int) buffer[0]]; 
+         (opcode < opcode_end) && (buffer[0] == opcode->opcode[0]);
+         opcode++) {
+      const struct s390_operand *operand;
+      const unsigned char *opindex;
+      int i;
+
+      /* check signature of the opcode */
+      if ((buffer[1] & opcode->mask[1]) != opcode->opcode[1] ||
+          (buffer[2] & opcode->mask[2]) != opcode->opcode[2] ||
+          (buffer[3] & opcode->mask[3]) != opcode->opcode[3] ||
+          (buffer[4] & opcode->mask[4]) != opcode->opcode[4] ||
+          (buffer[5] & opcode->mask[5]) != opcode->opcode[5])
+        continue;
+  
+      /* the instruction is valid */
+      if (opcode->operands[0] != 0)
+        (*info->fprintf_func) (info->stream, "%s\t", opcode->name);
+      else
+        (*info->fprintf_func) (info->stream, "%s", opcode->name);
+  
+      /* extract the operands */
+      separator = 0;
+      for (opindex = opcode->operands; *opindex != 0; opindex++) {
+        char *insn;
+        unsigned int value;
+
+        operand = s390_operands + *opindex;
+        value = s390_extract_operand(buffer, operand);
+
+        if ((operand->flags & S390_OPERAND_INDEX) && value == 0)
+          continue;
+        if ((operand->flags & S390_OPERAND_BASE) && 
+            value == 0 && separator == '(') {
+          separator = ',';
+          continue;
+        }
+
+        if (separator)
+          (*info->fprintf_func) (info->stream, "%c", separator);
+
+        if (operand->flags & S390_OPERAND_GPR)
+          (*info->fprintf_func) (info->stream, "%%r%i", value);
+        else if (operand->flags & S390_OPERAND_FPR)
+          (*info->fprintf_func) (info->stream, "%%f%i", value);
+        else if (operand->flags & S390_OPERAND_AR)
+          (*info->fprintf_func) (info->stream, "%%a%i", value);
+        else if (operand->flags & S390_OPERAND_CR)
+          (*info->fprintf_func) (info->stream, "%%c%i", value);
+        else if (operand->flags & S390_OPERAND_PCREL)
+          (*info->print_address_func) (memaddr + (signed short) value, info);
+        else if (operand->flags & S390_OPERAND_SIGNED)
+          (*info->fprintf_func) (info->stream, "%i",
+		                 (int) ((signed short) value));
+        else
+	  (*info->fprintf_func) (info->stream, "%i", value);
+
+        if (operand->flags & S390_OPERAND_DISP) {
+	  separator = '(';
+        } else if (operand->flags & S390_OPERAND_BASE) {
+	  (*info->fprintf_func) (info->stream, ")");
+          separator = ',';
+        } else
+	  separator = ',';
+      }
+
+      /* found instruction, printed it, return its size */
+      return opsize;
+    }
+    /* no matching instruction found, fall through to hex print  */
+  }
+
+  if (bufsize >= 4) {
+    value = (unsigned int) buffer[0];
+    value = (value << 8) + (unsigned int) buffer[1];
+    value = (value << 8) + (unsigned int) buffer[2];
+    value = (value << 8) + (unsigned int) buffer[3];
+    (*info->fprintf_func) (info->stream,".long\t0x%08x", value);
+    return 4;
+  } else if (bufsize >= 2) {
+    value = (unsigned int) buffer[0];
+    value = (value << 8) + (unsigned int) buffer[1];
+    (*info->fprintf_func) (info->stream,".short\t0x%04x", value);
+    return 2;
+  } else {
+    value = (unsigned int) buffer[0];
+    (*info->fprintf_func) (info->stream,".byte\t0x%02x", value);
+    return 1;
+  }
+}
diff -u -r --new-file gdb-5.0/opcodes/s390-mkopc.c gdb-5.0-s390/opcodes/s390-mkopc.c
--- gdb-5.0/opcodes/s390-mkopc.c	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/opcodes/s390-mkopc.c	Tue Jul 18 19:16:46 2000
@@ -0,0 +1,133 @@
+/* s390-mkopc.c -- Generates opcode table out of s390-opc.txt
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct op_struct {
+	char  opcode[16];
+	char  mnemonic[16];
+	char  format[16];
+        unsigned long long sort_value;
+        int   no_nibbles;
+};
+
+struct op_struct *op_array;
+int max_ops;
+int no_ops;
+
+static void
+createTable(void)
+{
+    max_ops = 256;
+    op_array = malloc(max_ops*sizeof(struct op_struct));
+    no_ops = 0;
+}
+
+/*
+ *  `insertOpcode': insert an op_struct into sorted opcode array 
+ */
+static void
+insertOpcode(char *opcode, char *mnemonic, char *format)
+{
+    char *str;
+    unsigned long long sort_value;
+    int no_nibbles;
+    int ix, k;
+
+    while (no_ops >= max_ops) {
+      max_ops = max_ops*2;
+      op_array = realloc(op_array, max_ops*sizeof(struct op_struct));
+    }
+    sort_value = 0;
+    str = opcode;
+    for (ix = 0; ix < 16; ix++) {
+      if (*str >= '0' && *str <= '9')
+	sort_value = (sort_value << 4) + (*str - '0');
+      else if (*str >= 'a' && *str <= 'f')
+	sort_value = (sort_value << 4) + (*str - 'a' + 10);
+      else if (*str >= 'A' && *str <= 'F')
+	sort_value = (sort_value << 4) + (*str - 'A' + 10);
+      else if (*str == '?')
+	sort_value <<= 4;
+      else
+	break;
+      str++;
+    }
+    sort_value <<= 4*(16 - ix);
+    no_nibbles = ix;
+    for (ix = 0; ix < no_ops; ix++)
+      if (sort_value > op_array[ix].sort_value)
+        break;
+    for (k = no_ops; k > ix; k--)
+      op_array[k] = op_array[k-1];
+    strcpy(op_array[ix].opcode, opcode);
+    strcpy(op_array[ix].mnemonic, mnemonic);
+    strcpy(op_array[ix].format, format);
+    op_array[ix].sort_value = sort_value;
+    op_array[ix].no_nibbles = no_nibbles;
+    no_ops++;
+}
+
+
+/*
+ *  `dumpTable': write opcode table
+ */
+static void
+dumpTable(void)
+{
+    char *str;
+    int  ix;
+
+    /*  Write hash table entries (slots). */
+    printf("const struct s390_opcode s390_opcodes[] = {\n");
+    for (ix = 0; ix < no_ops; ix++) {
+      printf("  { \"%s\",\t ", op_array[ix].mnemonic);
+      for (str = op_array[ix].opcode; *str != 0; str++)
+	if (*str == '?')
+	  *str = '0';
+      printf("OP%i(0x%sLL),\t ", 
+	     op_array[ix].no_nibbles*4, op_array[ix].opcode);
+      printf("MASK_%s,\t INSTR_%s\t}",
+             op_array[ix].format, op_array[ix].format);
+      if (ix < no_ops-1)
+	printf(",\n");
+      else
+	printf("\n");
+    }
+    printf("};\n\n");
+    printf("const int s390_num_opcodes =\n");
+    printf("  sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n");
+}
+
+
+int
+main(void)
+{
+    char currentLine[256];
+
+    createTable();
+    /*  Read opcode descriptions from `stdin'.  For each mnemonic,
+     *  make an entry into the opcode table.
+     */
+    while (fgets(currentLine, sizeof(currentLine), stdin) != NULL) {
+	char  opcode[16];
+	char  mnemonic[16];
+	char  format[16];
+
+	if (currentLine[0] == '#')
+	  continue;
+	memset(opcode, 0, 8);
+	if (sscanf(currentLine,
+		   "%15s %15s %15s", opcode, mnemonic, format) == 3) {
+	  insertOpcode(opcode, mnemonic, format);
+	}
+    }
+
+    dumpTable();
+    return 0;
+}
diff -u -r --new-file gdb-5.0/opcodes/s390-opc.c gdb-5.0-s390/opcodes/s390-opc.c
--- gdb-5.0/opcodes/s390-opc.c	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/opcodes/s390-opc.c	Tue Jul 18 19:16:46 2000
@@ -0,0 +1,675 @@
+/* s390-opc.c -- S390 opcode list
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+
+This file is part of GDB, GAS, and the GNU binutils.
+
+GDB, GAS, and the GNU binutils are free software; you can redistribute
+them and/or modify them 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, GAS, and the 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 file; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#include <stdio.h>
+#include "ansidecl.h"
+#include "opcode/s390.h"
+
+/* TODO: 1) correct forms for vector instructions. 
+ *       2) change OPXX_MASK to reflect the 'reserved' bits of
+ *          instructions with 'holes' in them
+ */
+
+/* This file holds the S390 opcode table.  The opcode table
+   includes almost all of the extended instruction mnemonics.  This
+   permits the disassembler to use them, and simplifies the assembler
+   logic, at the cost of increasing the table size.  The table is
+   strictly constant data, so the compiler should be able to put it in
+   the .text section.
+
+   This file also holds the operand table.  All knowledge about
+   inserting operands into instructions and vice-versa is kept in this
+   file.  */
+
+/* The operands table.
+   The fields are bits, shift, insert, extract, flags.  */
+
+const struct s390_operand s390_operands[] =
+{
+#define UNUSED 0
+  { 0, 0, 0 },                    /* Indicates the end of the operand list */
+
+#define R_8    1                  /* GPR starting at position 8 */
+  { 4, 8, S390_OPERAND_GPR },
+#define R_12   2                  /* GPR starting at position 12 */
+  { 4, 12, S390_OPERAND_GPR },    
+#define R_16   3                  /* GPR starting at position 16 */
+  { 4, 16, S390_OPERAND_GPR },    
+#define R_20   4                  /* GPR starting at position 20 */
+  { 4, 20, S390_OPERAND_GPR },    
+#define R_24   5                  /* GPR starting at position 24 */
+  { 4, 24, S390_OPERAND_GPR },    
+#define R_28   6                  /* GPR starting at position 28 */
+  { 4, 28, S390_OPERAND_GPR },    
+#define R_32   7                  /* GPR starting at position 32 */
+  { 4, 32, S390_OPERAND_GPR },
+
+#define F_8    8                  /* FPR starting at position 8 */
+  { 4, 8, S390_OPERAND_FPR },
+#define F_12   9                  /* FPR starting at position 12 */
+  { 4, 12, S390_OPERAND_FPR },
+#define F_24   10                 /* FPR starting at position 24 */
+  { 4, 24, S390_OPERAND_FPR },
+#define F_28   11                 /* FPR starting at position 28 */
+  { 4, 28, S390_OPERAND_FPR },
+#define F_32   12                 /* FPR starting at position 32 */
+  { 4, 32, S390_OPERAND_FPR },
+
+#define A_8    13                 /* Access reg. starting at position 8 */
+  { 4, 8, S390_OPERAND_AR },
+#define A_12   14                 /* Access reg. starting at position 12 */
+  { 4, 12, S390_OPERAND_AR },
+#define A_24   15                 /* Access reg. starting at position 24 */
+  { 4, 24, S390_OPERAND_AR },
+#define A_28   16                 /* Access reg. starting at position 28 */
+  { 4, 28, S390_OPERAND_AR },
+
+#define C_8    17                 /* Control reg. starting at position 8 */
+  { 4, 8, S390_OPERAND_CR },
+#define C_12   18                 /* Control reg. starting at position 12 */
+  { 4, 12, S390_OPERAND_CR },
+
+#define B_16   19                 /* Base register starting at position 16 */
+  { 4, 16, S390_OPERAND_BASE|S390_OPERAND_GPR },   
+#define B_32   20                 /* Base register starting at position 32 */
+  { 4, 32, S390_OPERAND_BASE|S390_OPERAND_GPR },   
+
+#define X_12   21                 /* Index register starting at position 12 */
+  { 4, 12, S390_OPERAND_INDEX|S390_OPERAND_GPR },                   
+
+#define D_20   22                 /* Displacement starting at position 20 */
+  { 12, 20, S390_OPERAND_DISP },  
+#define D_36   23                 /* Displacement starting at position 36 */
+  { 12, 36, S390_OPERAND_DISP },  
+
+#define L4_8   24                 /* 4 bit length starting at position 8 */
+  { 4, 8, S390_OPERAND_LENGTH },                         
+#define L4_12  25                 /* 4 bit length starting at position 12 */
+  { 4, 12, S390_OPERAND_LENGTH },
+#define L8_8   26                 /* 8 bit length starting at position 8 */
+  { 8, 8, S390_OPERAND_LENGTH },                    
+
+#define U4_8   27                 /* 4 bit unsigned value starting at 8 */
+  { 4, 8, 0 },
+#define U4_12  28                 /* 4 bit unsigned value starting at 12 */
+  { 4, 12, 0 },
+#define U4_16  29                 /* 4 bit unsigned value starting at 16 */
+  { 4, 16, 0 },
+#define U4_20  30                 /* 4 bit unsigned value starting at 20 */
+  { 4, 20, 0 },
+#define U8_8   31                 /* 8 bit unsigned value starting at 8 */
+  { 8, 8, 0 },                    
+#define U8_16  32                 /* 8 bit unsigned value starting at 16 */
+  { 8, 16, 0 },
+#define I16_16 33                 /* 16 bit signed value starting at 16 */
+  { 16, 16, S390_OPERAND_SIGNED },
+#define U16_16 34                 /* 16 bit unsigned value starting at 16 */
+  { 16, 16, 0 },                  
+#define J16_16 35                 /* PC relative jump offset @ 16 */
+  { 16, 16, S390_OPERAND_PCREL }  
+};
+
+
+/* Macros used to form opcodes.  */
+
+/* 8/16/48 bit opcodes */
+#define OP8(x) { x, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define OP16(x) { x>>8, x&255, 0x00, 0x00, 0x00, 0x00 }
+#define OP48(x) { x>>40, (x>>32)&255, (x>>24)&255, \
+                  (x>>16)&255, (x>>8)&255, x&255}
+
+#define INSTR_E      2, { 0,0,0,0,0,0 }                  /* e.g. pr   */
+#define INSTR_RR     2, { R_8,R_12,0,0,0,0 }             /* e.g. lr   */
+#define INSTR_RR_M   2, { U4_8,R_12,0,0,0,0 }            /* e.g. bcr  */
+#define INSTR_RR_B   2, { R_12, 0,0,0,0,0 }              /* e.g. br   */
+#define INSTR_RR_I   2, { U8_8, 0,0,0,0,0 }              /* e.g. svc  */
+#define INSTR_RR_R   2, { R_8, 0,0,0,0,0 }               /* e.g. spm  */
+#define INSTR_RR_E   2, { R_8,R_12,0,0,0,0 }             /* e.g. aer  */
+#define INSTR_RR_D   2, { F_8,F_12,0,0,0,0 }             /* e.g. adr  */
+#define INSTR_RR_X   2, { R_8,R_12,0,0,0,0 }             /* e.g. mxr  */
+#define INSTR_RR_ED  2, { F_8,F_12,0,0,0,0 }             /* e.g. mer  */
+#define INSTR_RR_DE  2, { F_8,F_12,0,0,0,0 }             /* e.g. lrer */
+#define INSTR_RR_DX  2, { F_8,F_12,0,0,0,0 }             /* e.g. mxdr */
+#define INSTR_RR_XD  2, { F_8,F_12,0,0,0,0 }             /* e.g. lrdr */
+#define INSTR_RRE    4, { R_24,R_28,0,0,0,0 }            /* e.g. lura */
+#define INSTR_RRE_A  4, { A_24,A_28,0,0,0,0 }            /* e.g. cpya */
+#define INSTR_RRE_F  4, { F_24,F_28,0,0,0,0 }            /* e.g. debr */
+#define INSTR_RRE_O  4, { 0,0,0,0,0,0 }                  /* e.g. palb */
+#define INSTR_RRE_R  4, { R_24,0,0,0,0,0 }               /* e.g. ipm  */
+#define INSTR_RRE_E  4, { F_24,0,0,0,0,0 }               /* e.g. sqer */
+#define INSTR_RRE_D  4, { F_24,0,0,0,0,0 }               /* e.g. sqdr */
+#define INSTR_RRE_X  4, { F_24,0,0,0,0,0 }               /* e.g. dxr  */
+#define INSTR_RRE_AR 4, { A_24,R_28,0,0,0,0 }            /* e.g. sar  */
+#define INSTR_RRE_RA 4, { R_24,A_28,0,0,0,0 }            /* e.g. ear  */
+#define INSTR_RRF_M  4, { R_24,U4_16,R_28,0,0,0 }        /* e.g. cfxbr*/
+#define INSTR_RRF_RM 4, { R_24,R_16,R_28,U4_20,0,0 }     /* e.g. didbr*/
+#define INSTR_RRF_R  4, { R_16,R_24,R_28,0,0,0 }         /* e.g. madbr*/
+#define INSTR_RS     4, { R_8,R_12,D_20,B_16,0,0 }       /* e.g. cs   */
+#define INSTR_RS_A   4, { A_8,A_12,D_20,B_16,0,0 }       /* e.g. lam  */
+#define INSTR_RS_C   4, { C_8,C_12,D_20,B_16,0,0 }       /* e.g. lctl */
+#define INSTR_RS_M   4, { R_8,U4_12,D_20,B_16,0,0 }      /* e.g. icm  */
+#define INSTR_RS_S   4, { R_8,D_20,B_16,0,0,0 }          /* e.g. sll  */
+#define INSTR_RS_D   4, { R_8,D_20,B_16,0,0,0 }          /* e.g. sldl */
+#define INSTR_RX     4, { R_8,D_20,X_12,B_16,0,0 }       /* e.g. l    */
+#define INSTR_RX_M   4, { U4_8,D_20,X_12,B_16,0,0 }      /* e.g. bc   */
+#define INSTR_RX_B   4, { D_20,X_12,B_16,0,0,0 }         /* e.g. b    */
+#define INSTR_RX_E   4, { F_8,D_20,X_12,B_16,0,0 }       /* e.g. ae   */
+#define INSTR_RX_D   4, { F_8,D_20,X_12,B_16,0,0 }       /* e.g. ad   */
+#define INSTR_RX_ED  4, { F_8,D_20,X_12,B_16,0,0 }       /* e.g. me   */
+#define INSTR_RX_DX  4, { F_8,D_20,X_12,B_16,0,0 }       /* e.g. mxd  */
+#define INSTR_RXE    6, { F_8,D_20,X_12,B_16,0,0 }       /* e.g. axbr */
+#define INSTR_RXF    6, { F_32,D_20,X_12,B_16,F_8,0 }    /* e.g. madb */
+#define INSTR_S      4, { D_20,B_16,0,0,0,0 }            /* e.g. lpsw */
+#define INSTR_S_O    4, { 0,0,0,0,0,0 }                  /* e.g. hsch */
+#define INSTR_SI     4, { D_20,B_16,U8_8,0,0,0 }         /* e.g. cli  */
+#define INSTR_SS_RR  6, { D_20,R_8,B_16,D_36,B_32,R_12 } /* e.g. mvck */
+#define INSTR_SS_LL  6, { D_20,L4_8,B_16,D_36,L4_12,B_32 } /* e.g. pack */
+#define INSTR_SS_LI  6, { D_20,L4_8,B_16,D_36,B_32,U4_12 } /* e.g. srp  */
+#define INSTR_SS_L   6, { D_20,L8_8,B_16,D_36,B_32,0 }   /* e.g. mvc  */
+#define INSTR_SSE    6, { D_20,B_16,D_36,B_32,0,0 }      /* e.g. mvsdk */
+#define INSTR_RI     4, { R_8,I16_16,0,0,0,0 }           /* e.g. ahi  */
+#define INSTR_RI_U   4, { R_8,U16_16,0,0,0,0 }           /* e.g. tml  */
+#define INSTR_RI_A   4, { R_8,J16_16,0,0,0,0 }           /* e.g. brct */
+#define INSTR_RI_MA  4, { U4_8,J16_16,0,0,0 }            /* e.g. brc  */
+#define INSTR_RI_B   4, { J16_16,0,0,0,0 }               /* e.g. j    */
+#define INSTR_RSI_A  4, { R_8,R_12,J16_16,0,0,0 }        /* e.g. brxh */
+#define INSTR_VR     4, { 0,0,0,0,0,0 }                  /* no support */
+#define INSTR_VS     4, { 0,0,0,0,0,0 }                  /* no support */
+#define INSTR_VST    4, { 0,0,0,0,0,0 }                  /* no support */
+#define INSTR_VV     4, { 0,0,0,0,0,0 }                  /* no support */
+#define INSTR_RSE    6, { 0,0,0,0,0,0 }                  /* no support */
+#define INSTR_QST    4, { 0,0,0,0,0,0 }                  /* no support */
+#define INSTR_QV     4, { 0,0,0,0,0,0 }                  /* no support */
+ 
+#define MASK_E      { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR     { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_M   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_B   { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_I   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_R   { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_E   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_D   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_X   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_ED  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_DE  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_DX  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RR_XD  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RRE    { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 }
+#define MASK_RRE_A  { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 }
+#define MASK_RRE_F  { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 }
+#define MASK_RRE_O  { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
+#define MASK_RRE_R  { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 }
+#define MASK_RRE_E  { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 }
+#define MASK_RRE_D  { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 }
+#define MASK_RRE_X  { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 }
+#define MASK_RRE_AR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 }
+#define MASK_RRE_RA { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 }
+#define MASK_RRF_M  { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RRF_RM { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RRF_R  { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RS     { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RS_A   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RS_C   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RS_M   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RS_S   { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RS_D   { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RX     { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RX_M   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RX_B   { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RX_E   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RX_D   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RX_ED  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RX_DX  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RXE    { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
+#define MASK_RXF    { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
+#define MASK_S      { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_S_O    { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
+#define MASK_SI     { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_SS_RR  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_SS_LL  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_SS_LI  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_SS_L   { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_SSE    { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RI     { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RI_U   { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RI_A   { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RI_MA  { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RI_B   { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RSI_A  { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_VR     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_VS     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_VST    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_VV     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_RSE    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_QST    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define MASK_QV     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ 
+/* The opcode table.
+
+   The format of the opcode table is:
+
+   NAME	     OPCODE	MASK	OPERANDS
+
+   NAME is the name of the instruction.
+   OPCODE is the instruction opcode.
+   MASK is the opcode mask; this is used to tell the disassembler
+     which bits in the actual opcode must match OPCODE.
+   OPERANDS is the list of operands.
+
+   The disassembler reads the table in order and prints the first
+   instruction which matches. */
+
+const struct s390_opcode s390_opcodes[] = {
+  { "dp",	 OP8(0xfdLL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "mp",	 OP8(0xfcLL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "sp",	 OP8(0xfbLL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "ap",	 OP8(0xfaLL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "cp",	 OP8(0xf9LL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "zap",	 OP8(0xf8LL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "unpk",	 OP8(0xf3LL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "pack",	 OP8(0xf2LL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "mvo",	 OP8(0xf1LL),	 MASK_SS_LL,	 INSTR_SS_LL	},
+  { "srp",	 OP8(0xf0LL),	 MASK_SS_LI,	 INSTR_SS_LI	},
+  { "msdb",	 OP48(0xed000000001fLL),	 MASK_RXF,	 INSTR_RXF	},
+  { "madb",	 OP48(0xed000000001eLL),	 MASK_RXF,	 INSTR_RXF	},
+  { "ddb",	 OP48(0xed000000001dLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "mdb",	 OP48(0xed000000001cLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "sdb",	 OP48(0xed000000001bLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "adb",	 OP48(0xed000000001aLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "cdb",	 OP48(0xed0000000019LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "kdb",	 OP48(0xed0000000018LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "meeb",	 OP48(0xed0000000017LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "sqdb",	 OP48(0xed0000000015LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "sqeb",	 OP48(0xed0000000014LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "tcxb",	 OP48(0xed0000000012LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "tcdb",	 OP48(0xed0000000011LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "tceb",	 OP48(0xed0000000010LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "mseb",	 OP48(0xed000000000fLL),	 MASK_RXF,	 INSTR_RXF	},
+  { "maeb",	 OP48(0xed000000000eLL),	 MASK_RXF,	 INSTR_RXF	},
+  { "deb",	 OP48(0xed000000000dLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "mdeb",	 OP48(0xed000000000cLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "seb",	 OP48(0xed000000000bLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "aeb",	 OP48(0xed000000000aLL),	 MASK_RXE,	 INSTR_RXE	},
+  { "ceb",	 OP48(0xed0000000009LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "keb",	 OP48(0xed0000000008LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "mxdb",	 OP48(0xed0000000007LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "lxeb",	 OP48(0xed0000000006LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "lxdb",	 OP48(0xed0000000005LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "ldeb",	 OP48(0xed0000000004LL),	 MASK_RXE,	 INSTR_RXE	},
+  { "mvcin",	 OP8(0xe8LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "mvcdk",	 OP16(0xe50fLL),	 MASK_SSE,	 INSTR_SSE	},
+  { "mvcsk",	 OP16(0xe50eLL),	 MASK_SSE,	 INSTR_SSE	},
+  { "tprot",	 OP16(0xe501LL),	 MASK_SSE,	 INSTR_SSE	},
+  { "lasp",	 OP16(0xe500LL),	 MASK_SSE,	 INSTR_SSE	},
+  { "edmk",	 OP8(0xdfLL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "ed",	 OP8(0xdeLL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "trt",	 OP8(0xddLL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "tr",	 OP8(0xdcLL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "mvcs",	 OP8(0xdbLL),	 MASK_SS_RR,	 INSTR_SS_RR	},
+  { "mvcp",	 OP8(0xdaLL),	 MASK_SS_RR,	 INSTR_SS_RR	},
+  { "mvck",	 OP8(0xd9LL),	 MASK_SS_RR,	 INSTR_SS_RR	},
+  { "xc",	 OP8(0xd7LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "oc",	 OP8(0xd6LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "clc",	 OP8(0xd5LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "nc",	 OP8(0xd4LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "mvz",	 OP8(0xd3LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "mvc",	 OP8(0xd2LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "mvn",	 OP8(0xd1LL),	 MASK_SS_L,	 INSTR_SS_L	},
+  { "icm",	 OP8(0xbfLL),	 MASK_RS_M,	 INSTR_RS_M	},
+  { "stcm",	 OP8(0xbeLL),	 MASK_RS_M,	 INSTR_RS_M	},
+  { "clm",	 OP8(0xbdLL),	 MASK_RS_M,	 INSTR_RS_M	},
+  { "cds",	 OP8(0xbbLL),	 MASK_RS,	 INSTR_RS	},
+  { "cs",	 OP8(0xbaLL),	 MASK_RS,	 INSTR_RS	},
+  { "lctl",	 OP8(0xb7LL),	 MASK_RS_C,	 INSTR_RS_C	},
+  { "stctl",	 OP8(0xb6LL),	 MASK_RS_C,	 INSTR_RS_C	},
+  { "cfxbr",	 OP16(0xb39aLL),	 MASK_RRF_M,	 INSTR_RRF_M	},
+  { "cfdbr",	 OP16(0xb399LL),	 MASK_RRF_M,	 INSTR_RRF_M	},
+  { "cfebr",	 OP16(0xb398LL),	 MASK_RRF_M,	 INSTR_RRF_M	},
+  { "cxfbr",	 OP16(0xb396LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "cdfbr",	 OP16(0xb395LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "cefbr",	 OP16(0xb394LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "efpc",	 OP16(0xb38cLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "sfpc",	 OP16(0xb384LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "fidbr",	 OP16(0xb35fLL),	 MASK_RRF_M,	 INSTR_RRF_M	},
+  { "didbr",	 OP16(0xb35bLL),	 MASK_RRF_RM,	 INSTR_RRF_RM	},
+  { "fiebr",	 OP16(0xb357LL),	 MASK_RRF_M,	 INSTR_RRF_M	},
+  { "diebr",	 OP16(0xb353LL),	 MASK_RRF_RM,	 INSTR_RRF_RM	},
+  { "dxbr",	 OP16(0xb34dLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "mxbr",	 OP16(0xb34cLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "sxbr",	 OP16(0xb34bLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "axbr",	 OP16(0xb34aLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "cxbr",	 OP16(0xb349LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "kxbr",	 OP16(0xb348LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "fixbr",	 OP16(0xb347LL),	 MASK_RRF_M,	 INSTR_RRF_M	},
+  { "lexbr",	 OP16(0xb346LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "ldxbr",	 OP16(0xb345LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "ledbr",	 OP16(0xb344LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lcxbr",	 OP16(0xb343LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "ltxbr",	 OP16(0xb342LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lnxbr",	 OP16(0xb341LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lpxbr",	 OP16(0xb340LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "msdbr",	 OP16(0xb31fLL),	 MASK_RRF_R,	 INSTR_RRF_R	},
+  { "madbr",	 OP16(0xb31eLL),	 MASK_RRF_R,	 INSTR_RRF_R	},
+  { "ddbr",	 OP16(0xb31dLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "mdbr",	 OP16(0xb31cLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "sdbr",	 OP16(0xb31bLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "adbr",	 OP16(0xb31aLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "cdbr",	 OP16(0xb319LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "kdbr",	 OP16(0xb318LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "meebr",	 OP16(0xb317LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "sqxbr",	 OP16(0xb316LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "sqdbr",	 OP16(0xb315LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "sqebr",	 OP16(0xb314LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lcdbr",	 OP16(0xb313LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "ltdbr",	 OP16(0xb312LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lndbr",	 OP16(0xb311LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lpdbr",	 OP16(0xb310LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "msebr",	 OP16(0xb30fLL),	 MASK_RRF_R,	 INSTR_RRF_R	},
+  { "maebr",	 OP16(0xb30eLL),	 MASK_RRF_R,	 INSTR_RRF_R	},
+  { "debr",	 OP16(0xb30dLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "mdebr",	 OP16(0xb30cLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "sebr",	 OP16(0xb30bLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "aebr",	 OP16(0xb30aLL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "cebr",	 OP16(0xb309LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "kebr",	 OP16(0xb308LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "mxdbr",	 OP16(0xb307LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lxebr",	 OP16(0xb306LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lxdbr",	 OP16(0xb305LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "ldebr",	 OP16(0xb304LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lcebr",	 OP16(0xb303LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "ltebr",	 OP16(0xb302LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lnebr",	 OP16(0xb301LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lpebr",	 OP16(0xb300LL),	 MASK_RRE_F,	 INSTR_RRE_F	},
+  { "lfpc",	 OP16(0xb29dLL),	 MASK_S,	 INSTR_S	},
+  { "stfpc",	 OP16(0xb29cLL),	 MASK_S,	 INSTR_S	},
+  { "srnm",	 OP16(0xb299LL),	 MASK_S,	 INSTR_S	},
+  { "sacf",	 OP16(0xb279LL),	 MASK_S,	 INSTR_S	},
+  { "cmpsc",	 OP16(0xb263LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "srst",	 OP16(0xb25eLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "clst",	 OP16(0xb25dLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "bsg",	 OP16(0xb258LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "cuse",	 OP16(0xb257LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "mvst",	 OP16(0xb255LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "mvpg",	 OP16(0xb254LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "msr",	 OP16(0xb252LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "ear",	 OP16(0xb24fLL),	 MASK_RRE_RA,	 INSTR_RRE_RA	},
+  { "sar",	 OP16(0xb24eLL),	 MASK_RRE_AR,	 INSTR_RRE_AR	},
+  { "cpya",	 OP16(0xb24dLL),	 MASK_RRE_A,	 INSTR_RRE_A	},
+  { "tar",	 OP16(0xb24cLL),	 MASK_RRE_AR,	 INSTR_RRE_AR	},
+  { "lura",	 OP16(0xb24bLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "esta",	 OP16(0xb24aLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "ereg",	 OP16(0xb249LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "palb",	 OP16(0xb248LL),	 MASK_RRE_O,	 INSTR_RRE_O	},
+  { "msta",	 OP16(0xb247LL),	 MASK_RRE_R,	 INSTR_RRE_R	},
+  { "stura",	 OP16(0xb246LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "sqer",	 OP16(0xb245LL),	 MASK_RRE_E,	 INSTR_RRE_E	},
+  { "sqdr",	 OP16(0xb244LL),	 MASK_RRE_D,	 INSTR_RRE_D	},
+  { "cksm",	 OP16(0xb241LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "bakr",	 OP16(0xb240LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "schm",	 OP16(0xb23cLL),	 MASK_S_O,	 INSTR_S_O	},
+  { "rchp",	 OP16(0xb23bLL),	 MASK_S_O,	 INSTR_S_O	},
+  { "stcps",	 OP16(0xb23aLL),	 MASK_S,	 INSTR_S	},
+  { "stcrw",	 OP16(0xb239LL),	 MASK_S,	 INSTR_S	},
+  { "rsch",	 OP16(0xb238LL),	 MASK_S_O,	 INSTR_S_O	},
+  { "sal",	 OP16(0xb237LL),	 MASK_S_O,	 INSTR_S_O	},
+  { "tpi",	 OP16(0xb236LL),	 MASK_S,	 INSTR_S	},
+  { "tsch",	 OP16(0xb235LL),	 MASK_S,	 INSTR_S	},
+  { "stsch",	 OP16(0xb234LL),	 MASK_S,	 INSTR_S	},
+  { "ssch",	 OP16(0xb233LL),	 MASK_S,	 INSTR_S	},
+  { "msch",	 OP16(0xb232LL),	 MASK_S,	 INSTR_S	},
+  { "hsch",	 OP16(0xb231LL),	 MASK_S_O,	 INSTR_S_O	},
+  { "csch",	 OP16(0xb230LL),	 MASK_S_O,	 INSTR_S_O	},
+  { "dxr",	 OP16(0xb22dLL),	 MASK_RRE_X,	 INSTR_RRE_X	},
+  { "tb",	 OP16(0xb22cLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "sske",	 OP16(0xb22bLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "rrbe",	 OP16(0xb22aLL),	 MASK_RRE,	 INSTR_RRE	},
+  { "iske",	 OP16(0xb229LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "pt",	 OP16(0xb228LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "esar",	 OP16(0xb227LL),	 MASK_RRE_R,	 INSTR_RRE_R	},
+  { "epar",	 OP16(0xb226LL),	 MASK_RRE_R,	 INSTR_RRE_R	},
+  { "ssar",	 OP16(0xb225LL),	 MASK_RRE_R,	 INSTR_RRE_R	},
+  { "iac",	 OP16(0xb224LL),	 MASK_RRE_R,	 INSTR_RRE_R	},
+  { "ivsk",	 OP16(0xb223LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "ipm",	 OP16(0xb222LL),	 MASK_RRE_R,	 INSTR_RRE_R	},
+  { "ipte",	 OP16(0xb221LL),	 MASK_RRE,	 INSTR_RRE	},
+  { "cfc",	 OP16(0xb21aLL),	 MASK_S,	 INSTR_S	},
+  { "sac",	 OP16(0xb219LL),	 MASK_S,	 INSTR_S	},
+  { "pc",	 OP16(0xb218LL),	 MASK_S,	 INSTR_S	},
+  { "sie",	 OP16(0xb214LL),	 MASK_S,	 INSTR_S	},
+  { "stap",	 OP16(0xb212LL),	 MASK_S,	 INSTR_S	},
+  { "stpx",	 OP16(0xb211LL),	 MASK_S,	 INSTR_S	},
+  { "spx",	 OP16(0xb210LL),	 MASK_S,	 INSTR_S	},
+  { "ptlb",	 OP16(0xb20dLL),	 MASK_S_O,	 INSTR_S_O	},
+  { "ipk",	 OP16(0xb20bLL),	 MASK_S_O,	 INSTR_S_O	},
+  { "spka",	 OP16(0xb20aLL),	 MASK_S,	 INSTR_S	},
+  { "stpt",	 OP16(0xb209LL),	 MASK_S,	 INSTR_S	},
+  { "spt",	 OP16(0xb208LL),	 MASK_S,	 INSTR_S	},
+  { "stckc",	 OP16(0xb207LL),	 MASK_S,	 INSTR_S	},
+  { "sckc",	 OP16(0xb206LL),	 MASK_S,	 INSTR_S	},
+  { "stck",	 OP16(0xb205LL),	 MASK_S,	 INSTR_S	},
+  { "sck",	 OP16(0xb204LL),	 MASK_S,	 INSTR_S	},
+  { "stidp",	 OP16(0xb202LL),	 MASK_S,	 INSTR_S	},
+  { "lra",	 OP8(0xb1LL),	 MASK_RX,	 INSTR_RX	},
+  { "mc",	 OP8(0xafLL),	 MASK_SI,	 INSTR_SI	},
+  { "sigp",	 OP8(0xaeLL),	 MASK_RS,	 INSTR_RS	},
+  { "stosm",	 OP8(0xadLL),	 MASK_SI,	 INSTR_SI	},
+  { "stnsm",	 OP8(0xacLL),	 MASK_SI,	 INSTR_SI	},
+  { "clcle",	 OP8(0xa9LL),	 MASK_RS,	 INSTR_RS	},
+  { "mvcle",	 OP8(0xa8LL),	 MASK_RS,	 INSTR_RS	},
+  { "j",	 OP16(0xa7f4LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jno",	 OP16(0xa7e4LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jnp",	 OP16(0xa7d4LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jnh",	 OP16(0xa7d4LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jnm",	 OP16(0xa7b4LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jnl",	 OP16(0xa7b4LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jz",	 OP16(0xa784LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "je",	 OP16(0xa784LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jnz",	 OP16(0xa774LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jne",	 OP16(0xa774LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jm",	 OP16(0xa744LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jl",	 OP16(0xa744LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jp",	 OP16(0xa724LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jh",	 OP16(0xa724LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "jo",	 OP16(0xa714LL),	 MASK_RI_B,	 INSTR_RI_B	},
+  { "chi",	 OP16(0xa70eLL),	 MASK_RI,	 INSTR_RI	},
+  { "mhi",	 OP16(0xa70cLL),	 MASK_RI,	 INSTR_RI	},
+  { "ahi",	 OP16(0xa70aLL),	 MASK_RI,	 INSTR_RI	},
+  { "lhi",	 OP16(0xa708LL),	 MASK_RI,	 INSTR_RI	},
+  { "brct",	 OP16(0xa706LL),	 MASK_RI_A,	 INSTR_RI_A	},
+  { "bras",	 OP16(0xa705LL),	 MASK_RI_A,	 INSTR_RI_A	},
+  { "brc",	 OP16(0xa704LL),	 MASK_RI_MA,	 INSTR_RI_MA	},
+  { "tml",	 OP16(0xa701LL),	 MASK_RI_U,	 INSTR_RI_U	},
+  { "tmh",	 OP16(0xa700LL),	 MASK_RI_U,	 INSTR_RI_U	},
+  { "stam",	 OP8(0x9bLL),	 MASK_RS_A,	 INSTR_RS_A	},
+  { "lam",	 OP8(0x9aLL),	 MASK_RS_A,	 INSTR_RS_A	},
+  { "trace",	 OP8(0x99LL),	 MASK_RS,	 INSTR_RS	},
+  { "lm",	 OP8(0x98LL),	 MASK_RS,	 INSTR_RS	},
+  { "xi",	 OP8(0x97LL),	 MASK_SI,	 INSTR_SI	},
+  { "oi",	 OP8(0x96LL),	 MASK_SI,	 INSTR_SI	},
+  { "cli",	 OP8(0x95LL),	 MASK_SI,	 INSTR_SI	},
+  { "ni",	 OP8(0x94LL),	 MASK_SI,	 INSTR_SI	},
+  { "ts",	 OP8(0x93LL),	 MASK_S,	 INSTR_S	},
+  { "mvi",	 OP8(0x92LL),	 MASK_SI,	 INSTR_SI	},
+  { "tm",	 OP8(0x91LL),	 MASK_SI,	 INSTR_SI	},
+  { "stm",	 OP8(0x90LL),	 MASK_RS,	 INSTR_RS	},
+  { "slda",	 OP8(0x8fLL),	 MASK_RS_D,	 INSTR_RS_D	},
+  { "srda",	 OP8(0x8eLL),	 MASK_RS_D,	 INSTR_RS_D	},
+  { "sldl",	 OP8(0x8dLL),	 MASK_RS_D,	 INSTR_RS_D	},
+  { "srdl",	 OP8(0x8cLL),	 MASK_RS_D,	 INSTR_RS_D	},
+  { "sla",	 OP8(0x8bLL),	 MASK_RS_S,	 INSTR_RS_S	},
+  { "sra",	 OP8(0x8aLL),	 MASK_RS_S,	 INSTR_RS_S	},
+  { "sll",	 OP8(0x89LL),	 MASK_RS_S,	 INSTR_RS_S	},
+  { "srl",	 OP8(0x88LL),	 MASK_RS_S,	 INSTR_RS_S	},
+  { "bxle",	 OP8(0x87LL),	 MASK_RS,	 INSTR_RS	},
+  { "bxh",	 OP8(0x86LL),	 MASK_RS,	 INSTR_RS	},
+  { "brxle",	 OP8(0x85LL),	 MASK_RSI_A,	 INSTR_RSI_A	},
+  { "brxh",	 OP8(0x84LL),	 MASK_RSI_A,	 INSTR_RSI_A	},
+  { "diag",	 OP8(0x83LL),	 MASK_RS,	 INSTR_RS	},
+  { "lpsw",	 OP8(0x82LL),	 MASK_S,	 INSTR_S	},
+  { "ssm",	 OP8(0x80LL),	 MASK_S,	 INSTR_S	},
+  { "su",	 OP8(0x7fLL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "au",	 OP8(0x7eLL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "de",	 OP8(0x7dLL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "me",	 OP8(0x7cLL),	 MASK_RX_ED,	 INSTR_RX_ED	},
+  { "se",	 OP8(0x7bLL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "ae",	 OP8(0x7aLL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "ce",	 OP8(0x79LL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "le",	 OP8(0x78LL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "ms",	 OP8(0x71LL),	 MASK_RX,	 INSTR_RX	},
+  { "ste",	 OP8(0x70LL),	 MASK_RX_E,	 INSTR_RX_E	},
+  { "sw",	 OP8(0x6fLL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "aw",	 OP8(0x6eLL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "dd",	 OP8(0x6dLL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "md",	 OP8(0x6cLL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "sd",	 OP8(0x6bLL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "ad",	 OP8(0x6aLL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "cd",	 OP8(0x69LL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "ld",	 OP8(0x68LL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "mxd",	 OP8(0x67LL),	 MASK_RX_DX,	 INSTR_RX_DX	},
+  { "std",	 OP8(0x60LL),	 MASK_RX_D,	 INSTR_RX_D	},
+  { "sl",	 OP8(0x5fLL),	 MASK_RX,	 INSTR_RX	},
+  { "al",	 OP8(0x5eLL),	 MASK_RX,	 INSTR_RX	},
+  { "d",	 OP8(0x5dLL),	 MASK_RX,	 INSTR_RX	},
+  { "m",	 OP8(0x5cLL),	 MASK_RX,	 INSTR_RX	},
+  { "s",	 OP8(0x5bLL),	 MASK_RX,	 INSTR_RX	},
+  { "a",	 OP8(0x5aLL),	 MASK_RX,	 INSTR_RX	},
+  { "c",	 OP8(0x59LL),	 MASK_RX,	 INSTR_RX	},
+  { "l",	 OP8(0x58LL),	 MASK_RX,	 INSTR_RX	},
+  { "x",	 OP8(0x57LL),	 MASK_RX,	 INSTR_RX	},
+  { "o",	 OP8(0x56LL),	 MASK_RX,	 INSTR_RX	},
+  { "cl",	 OP8(0x55LL),	 MASK_RX,	 INSTR_RX	},
+  { "n",	 OP8(0x54LL),	 MASK_RX,	 INSTR_RX	},
+  { "lae",	 OP8(0x51LL),	 MASK_RX,	 INSTR_RX	},
+  { "st",	 OP8(0x50LL),	 MASK_RX,	 INSTR_RX	},
+  { "cvb",	 OP8(0x4fLL),	 MASK_RX,	 INSTR_RX	},
+  { "cvd",	 OP8(0x4eLL),	 MASK_RX,	 INSTR_RX	},
+  { "bas",	 OP8(0x4dLL),	 MASK_RX,	 INSTR_RX	},
+  { "mh",	 OP8(0x4cLL),	 MASK_RX,	 INSTR_RX	},
+  { "sh",	 OP8(0x4bLL),	 MASK_RX,	 INSTR_RX	},
+  { "ah",	 OP8(0x4aLL),	 MASK_RX,	 INSTR_RX	},
+  { "ch",	 OP8(0x49LL),	 MASK_RX,	 INSTR_RX	},
+  { "lh",	 OP8(0x48LL),	 MASK_RX,	 INSTR_RX	},
+  { "b",	 OP16(0x47f0LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bno",	 OP16(0x47e0LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bnp",	 OP16(0x47d0LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bnh",	 OP16(0x47d0LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bnm",	 OP16(0x47b0LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bnl",	 OP16(0x47b0LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bz",	 OP16(0x4780LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "be",	 OP16(0x4780LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bnz",	 OP16(0x4770LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bne",	 OP16(0x4770LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bm",	 OP16(0x4740LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bl",	 OP16(0x4740LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bp",	 OP16(0x4720LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bh",	 OP16(0x4720LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bo",	 OP16(0x4710LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bc",	 OP8(0x47LL),	 MASK_RX_M,	 INSTR_RX_M	},
+  { "nop",	 OP16(0x4700LL),	 MASK_RX_B,	 INSTR_RX_B	},
+  { "bct",	 OP8(0x46LL),	 MASK_RX,	 INSTR_RX	},
+  { "bal",	 OP8(0x45LL),	 MASK_RX,	 INSTR_RX	},
+  { "ex",	 OP8(0x44LL),	 MASK_RX,	 INSTR_RX	},
+  { "ic",	 OP8(0x43LL),	 MASK_RX,	 INSTR_RX	},
+  { "stc",	 OP8(0x42LL),	 MASK_RX,	 INSTR_RX	},
+  { "la",	 OP8(0x41LL),	 MASK_RX,	 INSTR_RX	},
+  { "sth",	 OP8(0x40LL),	 MASK_RX,	 INSTR_RX	},
+  { "sur",	 OP8(0x3fLL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "aur",	 OP8(0x3eLL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "der",	 OP8(0x3dLL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "mer",	 OP8(0x3cLL),	 MASK_RR_ED,	 INSTR_RR_ED	},
+  { "ser",	 OP8(0x3bLL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "aer",	 OP8(0x3aLL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "cer",	 OP8(0x39LL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "ler",	 OP8(0x38LL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "sxr",	 OP8(0x37LL),	 MASK_RR_X,	 INSTR_RR_X	},
+  { "axr",	 OP8(0x36LL),	 MASK_RR,	 INSTR_RR	},
+  { "lrer",	 OP8(0x35LL),	 MASK_RR_DE,	 INSTR_RR_DE	},
+  { "her",	 OP8(0x34LL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "lcer",	 OP8(0x33LL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "lter",	 OP8(0x32LL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "lner",	 OP8(0x31LL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "lper",	 OP8(0x30LL),	 MASK_RR_E,	 INSTR_RR_E	},
+  { "swr",	 OP8(0x2fLL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "awr",	 OP8(0x2eLL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "ddr",	 OP8(0x2dLL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "mdr",	 OP8(0x2cLL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "sdr",	 OP8(0x2bLL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "adr",	 OP8(0x2aLL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "cdr",	 OP8(0x29LL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "ldr",	 OP8(0x28LL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "mxdr",	 OP8(0x27LL),	 MASK_RR_DX,	 INSTR_RR_DX	},
+  { "mxr",	 OP8(0x26LL),	 MASK_RR_X,	 INSTR_RR_X	},
+  { "lrdr",	 OP8(0x25LL),	 MASK_RR_XD,	 INSTR_RR_XD	},
+  { "hdr",	 OP8(0x24LL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "lcdr",	 OP8(0x23LL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "ltdr",	 OP8(0x22LL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "lndr",	 OP8(0x21LL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "lpdr",	 OP8(0x20LL),	 MASK_RR_D,	 INSTR_RR_D	},
+  { "slr",	 OP8(0x1fLL),	 MASK_RR,	 INSTR_RR	},
+  { "alr",	 OP8(0x1eLL),	 MASK_RR,	 INSTR_RR	},
+  { "dr",	 OP8(0x1dLL),	 MASK_RR,	 INSTR_RR	},
+  { "mr",	 OP8(0x1cLL),	 MASK_RR,	 INSTR_RR	},
+  { "sr",	 OP8(0x1bLL),	 MASK_RR,	 INSTR_RR	},
+  { "ar",	 OP8(0x1aLL),	 MASK_RR,	 INSTR_RR	},
+  { "cr",	 OP8(0x19LL),	 MASK_RR,	 INSTR_RR	},
+  { "lr",	 OP8(0x18LL),	 MASK_RR,	 INSTR_RR	},
+  { "xr",	 OP8(0x17LL),	 MASK_RR,	 INSTR_RR	},
+  { "or",	 OP8(0x16LL),	 MASK_RR,	 INSTR_RR	},
+  { "clr",	 OP8(0x15LL),	 MASK_RR,	 INSTR_RR	},
+  { "nr",	 OP8(0x14LL),	 MASK_RR,	 INSTR_RR	},
+  { "lcr",	 OP8(0x13LL),	 MASK_RR,	 INSTR_RR	},
+  { "ltr",	 OP8(0x12LL),	 MASK_RR,	 INSTR_RR	},
+  { "lnr",	 OP8(0x11LL),	 MASK_RR,	 INSTR_RR	},
+  { "lpr",	 OP8(0x10LL),	 MASK_RR,	 INSTR_RR	},
+  { "clcl",	 OP8(0x0fLL),	 MASK_RR,	 INSTR_RR	},
+  { "mvcl",	 OP8(0x0eLL),	 MASK_RR,	 INSTR_RR	},
+  { "basr",	 OP8(0x0dLL),	 MASK_RR,	 INSTR_RR	},
+  { "bassm",	 OP8(0x0cLL),	 MASK_RR,	 INSTR_RR	},
+  { "bsm",	 OP8(0x0bLL),	 MASK_RR,	 INSTR_RR	},
+  { "svc",	 OP8(0x0aLL),	 MASK_RR_I,	 INSTR_RR_I	},
+  { "br",	 OP16(0x07f0LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bnor",	 OP16(0x07e0LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bnpr",	 OP16(0x07d0LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bnhr",	 OP16(0x07d0LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bnmr",	 OP16(0x07b0LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bnlr",	 OP16(0x07b0LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bzr",	 OP16(0x0780LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "ber",	 OP16(0x0780LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bnzr",	 OP16(0x0770LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bner",	 OP16(0x0770LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bmr",	 OP16(0x0740LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "blr",	 OP16(0x0740LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bpr",	 OP16(0x0720LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bhr",	 OP16(0x0720LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bor",	 OP16(0x0710LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bcr",	 OP8(0x07LL),	 MASK_RR_M,	 INSTR_RR_M	},
+  { "nopr",	 OP16(0x0700LL),	 MASK_RR_B,	 INSTR_RR_B	},
+  { "bctr",	 OP8(0x06LL),	 MASK_RR,	 INSTR_RR	},
+  { "balr",	 OP8(0x05LL),	 MASK_RR,	 INSTR_RR	},
+  { "spm",	 OP8(0x04LL),	 MASK_RR_R,	 INSTR_RR_R	},
+  { "upt",	 OP16(0x0102LL),	 MASK_E,	 INSTR_E	},
+  { "pr",	 OP16(0x0101LL),	 MASK_E,	 INSTR_E	}
+};
+
+const int s390_num_opcodes =
+  sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);
+
diff -u -r --new-file gdb-5.0/opcodes/s390-opc.txt gdb-5.0-s390/opcodes/s390-opc.txt
--- gdb-5.0/opcodes/s390-opc.txt	Thu Jan  1 01:00:00 1970
+++ gdb-5.0-s390/opcodes/s390-opc.txt	Tue Jul 18 19:16:46 2000
@@ -0,0 +1,393 @@
+#  S/390 opcodes list. Use s390-mkopc to convert it into the opcode table.
+#  Copyright (C) 1999 Free Software Foundation, Inc.
+#  Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+#  Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+5a a RX "add" mchi
+6a ad RX_D "add normalized (long)" mchi
+2a adr RR_D "add normalized (long)" mchi
+7a ae RX_E "add normalized (short)" mchi
+3a aer RR_E "add normalized (short)" mchi
+4a ah RX "add halfword" mchi
+5e al RX "add logical" mchi
+1e alr RR "add logical" mchi
+fa ap SS_LL "add decimal" mchi
+1a ar RR "add" mchi
+7e au RX_E "add unnormalized (short)" mchi
+3e aur RR_E "add unnormalized (short)" mchi
+6e aw RX_D "add unnormalized (long)" mchi
+2e awr RR_D "add unnormalized (long)" mchi
+36 axr RR "add normalized" mchi
+b240 bakr RRE "branch and stack" mchi
+45 bal RX "branch and link" mchi
+05 balr RR "branch and link" mchi
+4d bas RX "branch and save" mchi
+0d basr RR "branch and save" mchi
+0c bassm RR "branch and save and set mode" mchi
+47 bc RX_M "branch on condition" mchi
+07 bcr RR_M "branch on condition" mchi
+46 bct RX "branch on count" mchi
+06 bctr RR "branch on count" mchi
+b258 bsg RRE "branch in subspace group" mchi
+0b bsm RR "branch and set mode" mchi
+86 bxh RS "branch on index high" mchi
+87 bxle RS "branch on index low or equal" mchi
+59 c RX "compare" mchi
+69 cd RX_D "compare (long)" mchi
+29 cdr RR_D "compare (long)" mchi
+bb cds RS "compare double and swap" mchi
+79 ce RX_E "compare (short)" mchi
+39 cer RR_E "compare (short)" mchi
+b21a cfc S "compare and form codeword" mchi
+49 ch RX "compare halfword" mchi
+55 cl RX "compare logical" mchi
+d5 clc SS_L "compare logical" mchi
+0f clcl RR "compare logical long" mchi
+95 cli SI "compare logical" mchi
+bd clm RS_M "compare logical characters under mask" mchi
+15 clr RR "compare logical" mchi
+b25d clst RRE "compare logical string" mchi
+b263 cmpsc RRE "compression call" mchi
+f9 cp SS_LL "compare decimal" mchi
+b24d cpya RRE_A "copy access" mchi
+19 cr RR "compare" mchi
+ba cs RS "compare and swap" mchi
+b230 csch S_O "clear subchannel" mchi
+b257 cuse RRE "compare until substring equal" mchi
+4f cvb RX "convert to binary" mchi
+4e cvd RX "convert to decimal" mchi
+5d d RX "divide" mchi
+6d dd RX_D "divide (long)" mchi
+2d ddr RR_D "divide (long)" mchi
+7d de RX_E "divide (short)" mchi
+3d der RR_E "divide (short)" mchi
+83 diag RS "diagnose" mchi
+fd dp SS_LL "divide decimal" mchi
+1d dr RR "divide" mchi
+b22d dxr RRE_X "divide (ext.)" mchi
+b24f ear RRE_RA "extract access" mchi
+de ed SS_L "edit" mchi
+df edmk SS_L "edit and mark" mchi
+b226 epar RRE_R "extract primary ASN" mchi
+b249 ereg RRE "extract stacked registers" mchi
+b227 esar RRE_R "extract secondary ASN" mchi
+b24a esta RRE "extract stacked state" mchi
+44 ex RX "execute" mchi
+24 hdr RR_D "halve (long)" mchi
+34 her RR_E "halve (short)" mchi
+b231 hsch S_O "halt subchannel" mchi
+b224 iac RRE_R "insert address space control" mchi
+43 ic RX "insert character" mchi
+bf icm RS_M "insert characters under mask" mchi
+b20b ipk S_O "insert PSW key" mchi
+b222 ipm RRE_R "insert program mask" mchi
+b221 ipte RRE "invalidate page table entry" mchi
+b229 iske RRE "insert storage key extended" mchi
+b223 ivsk RRE "insert virtual storage key" mchi
+58 l RX "load" mchi
+41 la RX "load address" mchi
+51 lae RX "load address extended" mchi
+9a lam RS_A "load access multiple" mchi
+e500 lasp SSE "load address space parameters" mchi
+23 lcdr RR_D "load complement (long)" mchi
+33 lcer RR_E "load complement (short)" mchi
+13 lcr RR "load complement" mchi
+b7 lctl RS_C "load control" mchi
+68 ld RX_D "load (long)" mchi
+28 ldr RR_D "load (long)" mchi
+78 le RX_E "load (short)" mchi
+38 ler RR_E "load (short)" mchi
+48 lh RX "load halfword" mchi
+98 lm RS "load multiple" mchi
+21 lndr RR_D "load negative (long)" mchi
+31 lner RR_E "load negative (short)" mchi
+11 lnr RR "load negative" mchi
+20 lpdr RR_D "load positive (long)" mchi
+30 lper RR_E "load positive (short)" mchi
+10 lpr RR "load positive" mchi
+82 lpsw S "load PSW" mchi
+18 lr RR "load" mchi
+b1 lra RX "load real address" mchi
+25 lrdr RR_XD "load rounded (ext. to long)" mchi
+35 lrer RR_DE "load rounded (long to short)" mchi
+22 ltdr RR_D "load and test (long)" mchi
+32 lter RR_E "load and test (short)" mchi
+12 ltr RR "load and test" mchi
+b24b lura RRE "load using real address" mchi
+5c m RX "multiply" mchi
+af mc SI "monitor call" mchi
+6c md RX_D "multiply (long)" mchi
+2c mdr RR_D "multiply (long)" mchi
+7c me RX_ED "multiply (short to long)" mchi
+3c mer RR_ED "multiply (short to long)" mchi
+4c mh RX "multiply halfword" mchi
+fc mp SS_LL "multiply decimal" mchi
+1c mr RR "multiply" mchi
+b232 msch S "modify subchannel" mchi
+b247 msta RRE_R "modify stacked state" mchi
+d2 mvc SS_L "move" mchi
+e50f mvcdk SSE "move with destination key" mchi
+e8 mvcin SS_L "move inverse" mchi
+d9 mvck SS_RR "move with key" mchi
+0e mvcl RR "move long" mchi
+da mvcp SS_RR "move to primary" mchi
+db mvcs SS_RR "move to secondary" mchi
+e50e mvcsk SSE "move with source key" mchi
+92 mvi SI "move" mchi
+d1 mvn SS_L "move numerics" mchi
+f1 mvo SS_LL "move with offset" mchi
+b254 mvpg RRE "move page" mchi
+b255 mvst RRE "move string" mchi
+d3 mvz SS_L "move zones" mchi
+67 mxd RX_DX "multiply (long to ext.)" mchi
+27 mxdr RR_DX "multiply (long to ext.)" mchi
+26 mxr RR_X "multiply (ext.)" mchi
+54 n RX "AND" mchi
+d4 nc SS_L "AND" mchi
+94 ni SI "AND" mchi
+14 nr RR "AND" mchi
+56 o RX "OR" mchi
+d6 oc SS_L "OR" mchi
+96 oi SI "OR" mchi
+16 or RR "OR" mchi
+f2 pack SS_LL "pack" mchi
+b248 palb RRE_O "purge ALB" mchi
+b218 pc S "program call" mchi
+0101 pr E "program return" mchi
+b228 pt RRE "program transfer" mchi
+b20d ptlb S_O "purge TLB" mchi
+b23b rchp S_O "reset channel path" mchi
+b22a rrbe RRE "reset reference bit extended" mchi
+b238 rsch S_O "resume subchannel" mchi
+5b s RX "subtract" mchi
+b219 sac S "set address space control" mchi
+b279 sacf S "set address space control fast" mchi
+b237 sal S_O "set address limit" mchi
+b24e sar RRE_AR "set access" mchi
+b23c schm S_O "set channel monitor" mchi
+b204 sck S "set clock" mchi
+b206 sckc S "set clock comparator" mchi
+6b sd RX_D "subtract normalized (long)" mchi
+2b sdr RR_D "subtract normalized (long)" mchi
+7b se RX_E "subtract normalized (short)" mchi
+3b ser RR_E "subtract normalized (short)" mchi
+4b sh RX "subtract halfword" mchi
+b214 sie S "start interpretive execution" mchi
+ae sigp RS "signal processor" mchi
+5f sl RX "subtract logical" mchi
+8b sla RS_S "shift left single" mchi
+8f slda RS_D "shift left double (long)" mchi
+8d sldl RS_D "shift left double logical (long)" mchi
+89 sll RS_S "shift left single logical" mchi
+1f slr RR "subtract logical" mchi
+fb sp SS_LL "subtract decimal" mchi
+b20a spka S "set PSW key from address" mchi
+04 spm RR_R "set program mask" mchi
+b208 spt S "set CPU timer" mchi
+b210 spx S "set prefix" mchi
+b244 sqdr RRE_D "square root (long)" mchi
+b245 sqer RRE_E "square root (short)" mchi
+1b sr RR "subtract" mchi
+8a sra RS_S "shift right single" mchi
+8e srda RS_D "shift right double (long)" mchi
+8c srdl RS_D "shift right double logical (long)" mchi
+88 srl RS_S "shift right single logical" mchi
+f0 srp SS_LI "shift and round decimal" mchi
+b25e srst RRE "search string" mchi
+b225 ssar RRE_R "set secondary ASN" mchi
+b233 ssch S "start subchannel" mchi
+b22b sske RRE "set storage key extended" mchi
+80 ssm S "set system mask" mchi
+50 st RX "store" mchi
+9b stam RS_A "store access multiple" mchi
+b212 stap S "store CPU address" mchi
+42 stc RX "store character" mchi
+b205 stck S "store clock" mchi
+b207 stckc S "store clock comparator" mchi
+be stcm RS_M "store characters under mask" mchi
+b23a stcps S "store channel path status" mchi
+b239 stcrw S "store channel report word" mchi
+b6 stctl RS_C "store control" mchi
+60 std RX_D "store (long)" mchi
+70 ste RX_E "store (short)" mchi
+40 sth RX "store halfword" mchi
+b202 stidp S "store CPU id" mchi
+90 stm RS "store multiple" mchi
+ac stnsm SI "store then AND system mask" mchi
+ad stosm SI "store then OR system mask" mchi
+b209 stpt S "store CPU timer" mchi
+b211 stpx S "store prefix" mchi
+b234 stsch S "store subchannel" mchi
+b246 stura RRE "store using real address" mchi
+7f su RX_E "subtract unnormalized (short)" mchi
+3f sur RR_E "subtract unnormalized (short)" mchi
+0a svc RR_I "supervisor call" mchi
+6f sw RX_D "subtract unnormalized (long)" mchi
+2f swr RR_D "subtract unnormalized (long)" mchi
+37 sxr RR_X "subtract normalized (ext.)" mchi
+b24c tar RRE_AR "test access" mchi
+b22c tb RRE "test block" mchi
+91 tm SI "test under mask" mchi
+b236 tpi S "test pending interruption" mchi
+e501 tprot SSE "test protection" mchi
+dc tr SS_L "translate" mchi
+99 trace RS "trace" mchi
+dd trt SS_L "translate and test" mchi
+93 ts S "test and set" mchi
+b235 tsch S "test subchannel" mchi
+f3 unpk SS_LL "unpack" mchi
+0102 upt E "update tree" mchi
+57 x RX "exclusive OR" mchi
+d7 xc SS_L "exclusive OR" mchi
+97 xi SI "exclusive OR" mchi
+17 xr RR "exclusive OR" mchi
+f8 zap SS_LL "zero and add" mchi
+a7?a ahi RI "add halfword immediate" mchi
+84 brxh RSI_A "branch relative on index high" mchi
+85 brxle RSI_A "branch relative on index low or equal" mchi
+a7?5 bras RI_A "branch relative and save" mchi
+a7?4 brc RI_MA "branch relative on condition" mchi
+a7?6 brct RI_A "branch relative on count" mchi
+b241 cksm RRE "checksum" mchi
+a7?e chi RI "compare halfword immediate" mchi
+a9 clcle RS "compare logical long extended" mchi
+a7?8 lhi RI "load halfword immediate" mchi
+a8 mvcle RS "move long extended" mchi
+a7?c mhi RI "multiply halfword immediate" mchi
+b252 msr RRE "multiply single" mchi
+71 ms RX "multiply single" mchi
+a7?0 tmh RI_U "test under mask high" mchi
+a7?1 tml RI_U "test under mask low" mchi
+070? nopr RR_B "no operation" xmni
+071? bor RR_B "branch on overflow / if ones" xmni
+072? bpr RR_B "branch on plus" xmni
+074? bmr RR_B "branch on minus / if mixed" xmni
+077? bnzr RR_B "branch on not zero / if not zeros" xmni
+078? bzr RR_B "branch on zero / if zeros" xmni
+07b? bnmr RR_B "branch on not minus / if not mixed" xmni
+07d? bnpr RR_B "branch on not plus" xmni
+07e? bnor RR_B "branch on not overflow / if not ones" xmni
+07f? br RR_B "unconditional branch" xmni
+470? nop RX_B "no operation" xmni
+471? bo RX_B "branch on overflow / if ones" xmni
+472? bp RX_B "branch on plus" xmni
+474? bm RX_B "branch on minus / if mixed" xmni
+477? bnz RX_B "branch on not zero / if not zeros" xmni
+478? bz RX_B "branch on zero / if zeros" xmni
+47b? bnm RX_B "branch on not minus / if not mixed" xmni
+47d? bnp RX_B "branch on not plus" xmni
+47e? bno RX_B "branch on not overflow / if not ones" xmni
+47f? b RX_B "unconditional branch" xmni
+a714 jo RI_B "jump on overflow / if ones" xmni
+a724 jp RI_B "jump on plus" xmni
+a744 jm RI_B "jump on minus / if mixed" xmni
+a774 jnz RI_B "jump on not zero / if not zeros" xmni
+a784 jz RI_B "jump on zero / if zeros" xmni
+a7b4 jnm RI_B "jump on not minus / if not mixed" xmni
+a7d4 jnp RI_B "jump on not plus" xmni
+a7e4 jno RI_B "jump on not overflow / if not ones" xmni
+a7f4 j RI_B "jump" xmni
+072? bhr RR_B "branch on A high" xmni
+074? blr RR_B "branch on A low" xmni
+077? bner RR_B "branch on A not equal B" xmni
+078? ber RR_B "branch on A equal B" xmni
+07b? bnlr RR_B "branch on A not low" xmni
+07d? bnhr RR_B "branch on A not high" xmni
+472? bh RX_B "branch on A high" xmni
+474? bl RX_B "branch on A low" xmni
+477? bne RX_B "branch on A not equal B" xmni
+478? be RX_B "branch on A equal B" xmni
+47b? bnl RX_B "branch on A not low" xmni
+47d? bnh RX_B "branch on A not high" xmni
+a724 jh RI_B "jump on A high" xmni
+a744 jl RI_B "jump on A low" xmni
+a774 jne RI_B "jump on A not equal B" xmni
+a784 je RI_B "jump on A equal B" xmni
+a7b4 jnl RI_B "jump on A not low" xmni
+a7d4 jnh RI_B "jump on A not high" xmni
+b34a axbr RRE_F "add extended bfp" mchi
+b31a adbr RRE_F "add long bfp" mchi
+ed000000001a adb RXE "add long bfp" mchi
+b30a aebr RRE_F "add short bfp" mchi
+ed000000000a aeb RXE "add short bfp" mchi
+b349 cxbr RRE_F "compare extended bfp" mchi
+b319 cdbr RRE_F "compare long bfp" mchi
+ed0000000019 cdb RXE "compare long bfp" mchi
+b309 cebr RRE_F "compare short bfp" mchi
+ed0000000009 ceb RXE "compare short bfp" mchi
+b348 kxbr RRE_F "compare and signal extended bfp" mchi
+b318 kdbr RRE_F "compare and signal long bfp" mchi
+ed0000000018 kdb RXE "compare and signal long bfp" mchi
+b308 kebr RRE_F "compare and signal short bfp" mchi
+ed0000000008 keb RXE "compare and signal short bfp" mchi
+b396 cxfbr RRE_F "convert from fixed 32 to extended bfp" mchi
+b395 cdfbr RRE_F "convert from fixed 32 to long bfp" mchi
+b394 cefbr RRE_F "convert from fixed 32 to short bfp" mchi
+b39a cfxbr RRF_M "convert to fixed extended bfp to 32" mchi
+b399 cfdbr RRF_M "convert to fixed long bfp to 32" mchi
+b398 cfebr RRF_M "convert to fixed short bfp to 32" mchi
+b34d dxbr RRE_F "divide extended bfp" mchi
+b31d ddbr RRE_F "divide long bfp" mchi
+ed000000001d ddb RXE "divide long bfp" mchi
+b30d debr RRE_F "divide short bfp" mchi
+ed000000000d deb RXE "divide short bfp" mchi
+b35b didbr RRF_RM "divide to integer long bfp" mchi
+b353 diebr RRF_RM "divide to integer short bfp" mchi
+b38c efpc RRE "extract fpc" mchi
+b342 ltxbr RRE_F "load and test extended bfp" mchi
+b312 ltdbr RRE_F "load and test long bfp" mchi
+b302 ltebr RRE_F "load and test short bfp" mchi
+b343 lcxbr RRE_F "load complement extended bfp" mchi
+b313 lcdbr RRE_F "load complement long bfp" mchi
+b303 lcebr RRE_F "load complement short bfp" mchi
+b347 fixbr RRF_M "load fp integer extended bfp" mchi
+b35f fidbr RRF_M "load fp integer long bfp" mchi
+b357 fiebr RRF_M "load fp integer short bfp" mchi
+b29d lfpc S "load fpc" mchi
+b305 lxdbr RRE_F "load lengthened long to extended bfp" mchi
+ed0000000005 lxdb RXE "load lengthened long to extended bfp" mchi
+b306 lxebr RRE_F "load lengthened short to extended bfp" mchi
+ed0000000006 lxeb RXE "load lengthened short to extended bfp" mchi
+b304 ldebr RRE_F "load lengthened short to long bfp" mchi
+ed0000000004 ldeb RXE "load lengthened short to long bfp" mchi
+b341 lnxbr RRE_F "load negative extended bfp" mchi
+b311 lndbr RRE_F "load negative long bfp" mchi
+b301 lnebr RRE_F "load negative short bfp" mchi
+b340 lpxbr RRE_F "load positive extended bfp" mchi
+b310 lpdbr RRE_F "load positive long bfp" mchi
+b300 lpebr RRE_F "load positive short bfp" mchi
+b345 ldxbr RRE_F "load rounded extended to long bfp" mchi
+b346 lexbr RRE_F "load rounded extended to short bfp" mchi
+b344 ledbr RRE_F "load rounded long to short bfp" mchi
+b34c mxbr RRE_F "multiply extended bfp" mchi
+b31c mdbr RRE_F "multiply long bfp" mchi
+ed000000001c mdb RXE "multiply long bfp" mchi
+b307 mxdbr RRE_F "multiply long to extended bfp" mchi
+ed0000000007 mxdb RXE "multiply long to extended bfp" mchi
+b317 meebr RRE_F "multiply short bfp" mchi
+ed0000000017 meeb RXE "multiply short bfp" mchi
+b30c mdebr RRE_F "multiply short to long bfp" mchi
+ed000000000c mdeb RXE "multiply short to long bfp" mchi
+b31e madbr RRF_R "multiply and add long bfp" mchi
+ed000000001e madb RXF "multiply and add long bfp" mchi
+b30e maebr RRF_R "multiply and add short bfp" mchi
+ed000000000e maeb RXF "multiply and add short bfp" mchi
+b31f msdbr RRF_R "multiply and subtract long bfp" mchi
+ed000000001f msdb RXF "multiply and subtract long bfp" mchi
+b30f msebr RRF_R "multiply and subtract short bfp" mchi
+ed000000000f mseb RXF "multiply and subtract short bfp" mchi
+b384 sfpc RRE "set fpc" mchi
+b299 srnm S "set rounding mode" mchi
+b316 sqxbr RRE_F "square root extended bfp" mchi
+b315 sqdbr RRE_F "square root long bfp" mchi
+ed0000000015 sqdb RXE "square root long bfp" mchi
+b314 sqebr RRE_F "square root short bfp" mchi
+ed0000000014 sqeb RXE "square root short bfp" mchi
+b29c stfpc S "store fpc" mchi
+b34b sxbr RRE_F "subtract extended bfp" mchi
+b31b sdbr RRE_F "subtract long bfp" mchi
+ed000000001b sdb RXE "subtract long bfp" mchi
+b30b sebr RRE_F "subtract short bfp" mchi
+ed000000000b seb RXE "subtract short bfp" mchi
+ed0000000012 tcxb RXE "test data class extended bfp" mchi
+ed0000000011 tcdb RXE "test data class long bfp" mchi
+ed0000000010 tceb RXE "test data class short bfp" mchi
diff -u -r --new-file gdb-5.0/readline/configure gdb-5.0-s390/readline/configure
--- gdb-5.0/readline/configure	Tue Aug  3 01:47:57 1999
+++ gdb-5.0-s390/readline/configure	Tue Jul 18 19:16:46 2000
@@ -2540,6 +2540,7 @@
 
 case "$host_cpu" in
 *cray*)	LOCAL_CFLAGS=-DCRAY ;;
+*s390*) LOCAL_CFLAGS=-fsigned-char ;;
 esac
 
 case "$host_os" in
diff -u -r --new-file gdb-5.0/readline/configure.in gdb-5.0-s390/readline/configure.in
--- gdb-5.0/readline/configure.in	Tue Aug  3 01:47:57 1999
+++ gdb-5.0-s390/readline/configure.in	Tue Jul 18 19:16:46 2000
@@ -127,6 +127,7 @@
 
 case "$host_cpu" in
 *cray*)	LOCAL_CFLAGS=-DCRAY ;;
+*s390*) LOCAL_CFLAGS=-fsigned-char ;;
 esac
 
 case "$host_os" in
GNU GENERAL PUBLIC LICENSE 

Version 2, June 1991 

Copyright (C) 1989, 1991 Free Software Foundation, Inc. 

59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 

Everyone is permitted to copy and distribute verbatim copies 

of this license document, but changing it is not allowed. 

Preamble 

The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public License is intended to 

guarantee your freedom to share and change free software--to make sure the
software is free for all its users. This General Public License applies to most of
the Free 

Software Foundation's software and to any other program whose authors
commit to using it. (Some other Free Software Foundation software is covered
by the 

GNU Library General Public License instead.) You can apply it to your programs,
too. 

When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to 

distribute copies of free software (and charge for this service if you wish), that
you receive source code or can get it if you want it, that you can change the
software 

or use pieces of it in new free programs; and that you know you can do these
things. 

To protect your rights, we need to make restrictions that forbid anyone to deny
you these rights or to ask you to surrender the rights. These restrictions translate
to 

certain responsibilities for you if you distribute copies of the software, or if you
modify it. 

For example, if you distribute copies of such a program, whether gratis or for a
fee, you must give the recipients all the rights that you have. You must make sure
that 

they, too, receive or can get the source code. And you must show them these
terms so they know their rights. 

We protect your rights with two steps: (1) copyright the software, and (2) offer
you this license which gives you legal permission to copy, distribute and/or modify 

the software. 

Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If the
software is 

modified by someone else and passed on, we want its recipients to know that
what they have is not the original, so that any problems introduced by others will
not 

reflect on the original authors' reputations. 

Finally, any free program is threatened constantly by software patents. We wish
to avoid the danger that redistributors of a free program will individually obtain 

patent licenses, in effect making the program proprietary. To prevent this, we
have made it clear that any patent must be licensed for everyone's free use or
not 

licensed at all. 

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
MODIFICATION 

0. This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms of this

General Public License. The "Program", below, refers to any such program or
work, and a "work based on the Program" means either the Program or any
derivative 

work under copyright law: that is to say, a work containing the Program or a
portion of it, either verbatim or with modifications and/or translated into another 

language. (Hereinafter, translation is included without limitation in the term
"modification".) Each licensee is addressed as "you". 

Activities other than copying, distribution and modification are not covered by this
License; they are outside its scope. The act of running the Program is not 

restricted, and the output from the Program is covered only if its contents
constitute a work based on the Program (independent of having been made by
running the 

Program). Whether that is true depends on what the Program does. 

1. You may copy and distribute verbatim copies of the Program's source code as
you receive it, in any medium, provided that you conspicuously and appropriately 

publish on each copy an appropriate copyright notice and disclaimer of warranty;
keep intact all the notices that refer to this License and to the absence of any 

warranty; and give any other recipients of the Program a copy of this License
along with the Program. 

You may charge a fee for the physical act of transferring a copy, and you may at
your option offer warranty protection in exchange for a fee. 

2. You may modify your copy or copies of the Program or any portion of it, thus
forming a work based on the Program, and copy and distribute such
modifications 

or work under the terms of Section 1 above, provided that you also meet all of
these conditions: 

a) You must cause the modified files to carry prominent notices stating that you
changed the files and the date of any change. 

b) You must cause any work that you distribute or publish, that in whole or in part
contains or is derived from the Program or any part thereof, to be licensed 

as a whole at no charge to all third parties under the terms of this License. 

c) If the modified program normally reads commands interactively when run, you
must cause it, when started running for such interactive use in the most 

ordinary way, to print or display an announcement including an appropriate
copyright notice and a notice that there is no warranty (or else, saying that you 

provide a warranty) and that users may redistribute the program under these
conditions, and telling the user how to view a copy of this License. (Exception: if 

the Program itself is interactive but does not normally print such an
announcement, your work based on the Program is not required to print an 

announcement.) 

These requirements apply to the modified work as a whole. If identifiable sections
of that work are not derived from the Program, and can be reasonably
considered 

independent and separate works in themselves, then this License, and its terms,
do not apply to those sections when you distribute them as separate works. But 

when you distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of this
License, 

whose permissions for other licensees extend to the entire whole, and thus to
each and every part regardless of who wrote it. 

Thus, it is not the intent of this section to claim rights or contest your rights to
work written entirely by you; rather, the intent is to exercise the right to control the

distribution of derivative or collective works based on the Program. 

In addition, mere aggregation of another work not based on the Program with the
Program (or with a work based on the Program) on a volume of a storage or 

distribution medium does not bring the other work under the scope of this
License. 

3. You may copy and distribute the Program (or a work based on it, under
Section 2) in object code or executable form under the terms of Sections 1 and 2
above 

provided that you also do one of the following: 

a) Accompany it with the complete corresponding machine-readable source
code, which must be distributed under the terms of Sections 1 and 2 above on a 

medium customarily used for software interchange; or, 

b) Accompany it with a written offer, valid for at least three years, to give any third
party, for a charge no more than your cost of physically performing source 

distribution, a complete machine-readable copy of the corresponding source
code, to be distributed under the terms of Sections 1 and 2 above on a medium 

customarily used for software interchange; or, 

c) Accompany it with the information you received as to the offer to distribute
corresponding source code. (This alternative is allowed only for noncommercial 

distribution and only if you received the program in object code or executable
form with such an offer, in accord with Subsection b above.) 

The source code for a work means the preferred form of the work for making
modifications to it. For an executable work, complete source code means all the 

source code for all modules it contains, plus any associated interface definition
files, plus the scripts used to control compilation and installation of the
executable. 

However, as a special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary form) with the
major 

components (compiler, kernel, and so on) of the operating system on which the
executable runs, unless that component itself accompanies the executable. 

If distribution of executable or object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the source
code from 

the same place counts as distribution of the source code, even though third
parties are not compelled to copy the source along with the object code. 

4. You may not copy, modify, sublicense, or distribute the Program except as
expressly provided under this License. Any attempt otherwise to copy, modify, 

sublicense or distribute the Program is void, and will automatically terminate your
rights under this License. However, parties who have received copies, or rights, 

from you under this License will not have their licenses terminated so long as
such parties remain in full compliance. 

5. You are not required to accept this License, since you have not signed it.
However, nothing else grants you permission to modify or distribute the Program
or its 

derivative works. These actions are prohibited by law if you do not accept this
License. Therefore, by modifying or distributing the Program (or any work based
on 

the Program), you indicate your acceptance of this License to do so, and all its
terms and conditions for copying, distributing or modifying the Program or works 

based on it. 

6. Each time you redistribute the Program (or any work based on the Program),
the recipient automatically receives a license from the original licensor to copy, 

distribute or modify the Program subject to these terms and conditions. You may
not impose any further restrictions on the recipients' exercise of the rights
granted 

herein. You are not responsible for enforcing compliance by third parties to this
License. 

7. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed on
you 

(whether by court order, agreement or otherwise) that contradict the conditions
of this License, they do not excuse you from the conditions of this License. If you 

cannot distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may not
distribute 

the Program at all. For example, if a patent license would not permit royalty-free
redistribution of the Program by all those who receive copies directly or indirectly 

through you, then the only way you could satisfy both it and this License would be
to refrain entirely from distribution of the Program. 

If any portion of this section is held invalid or unenforceable under any particular
circumstance, the balance of the section is intended to apply and the section as
a 

whole is intended to apply in other circumstances. 

It is not the purpose of this section to induce you to infringe any patents or other
property right claims or to contest validity of any such claims; this section has the 

sole purpose of protecting the integrity of the free software distribution system,
which is implemented by public license practices. Many people have made
generous 

contributions to the wide range of software distributed through that system in
reliance on consistent application of that system; it is up to the author/donor to
decide if 

he or she is willing to distribute software through any other system and a licensee
cannot impose that choice. 

This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License. 

8. If the distribution and/or use of the Program is restricted in certain countries
either by patents or by copyrighted interfaces, the original copyright holder who 

places the Program under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is permitted
only in or 

among countries not thus excluded. In such case, this License incorporates the
limitation as if written in the body of this License. 

9. The Free Software Foundation may publish revised and/or new versions of the
General Public License from time to time. Such new versions will be similar in
spirit 

to the present version, but may differ in detail to address new problems or
concerns. 

Each version is given a distinguishing version number. If the Program specifies a
version number of this License which applies to it and "any later version", you
have 

the option of following the terms and conditions either of that version or of any
later version published by the Free Software Foundation. If the Program does
not 

specify a version number of this License, you may choose any version ever
published by the Free Software Foundation. 

10. If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask for
permission. For 

software which is copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our decision will 

be guided by the two goals of preserving the free status of all derivatives of our
free software and of promoting the sharing and reuse of software generally. 

NO WARRANTY 

11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS
NO WARRANTY FOR THE PROGRAM, TO THE EXTENT 

PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED
IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER 

PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT 

LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO 

THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE 

COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED
TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY 

OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 

INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE 

THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED 

BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO
OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR 

OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES. 

END OF TERMS AND CONDITIONS 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]