This commit was manufactured by cvs2svn to create branch 'gdb_6_5-branch'.

Sprout from nickrob-async-20060513-branch 2006-05-12 01:45:11 UTC nobody 'This commit was manufactured by cvs2svn to create branch 'nickrob-'
Cherrypick from master 2006-05-14 22:27:26 UTC Nick Roberts <nickrob@snap.net.nz> '(gdbmi-send): Correct regexp for repeat commands.':
    ChangeLog
    bfd/version.h
    config.guess
    config.sub
    gdb/ChangeLog
    gdb/MAINTAINERS
    gdb/Makefile.in
    gdb/config/powerpc/nbsd.mh
    gdb/config/powerpc/nbsd.mt
    gdb/doc/ChangeLog
    gdb/doc/gdb.texinfo
    gdb/dwarf2read.c
    gdb/m2-lang.h
    gdb/m2-typeprint.c
    gdb/m2-valprint.c
    gdb/mi/gdb-mi.el
    gdb/ppcnbsd-nat.c
    gdb/ppcnbsd-tdep.c
    gdb/ppcnbsd-tdep.h
    gdb/version.in
    libiberty/ChangeLog
    libiberty/cplus-dem.c
    opcodes/ChangeLog
    opcodes/mips16-opc.c
diff --git a/ChangeLog b/ChangeLog
index 08a35ec..aee54b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-05-14  Ben Elliston  <bje@au.ibm.com>
+
+	* config.sub, config.guess: Update from upstream sources.
+
 2006-05-12  Ben Elliston  <bje@au.ibm.com>
 
 	* config.sub, config.guess: Update from upstream sources.
diff --git a/bfd/version.h b/bfd/version.h
index 4f0f1d5..1802147 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -1,3 +1,3 @@
-#define BFD_VERSION_DATE 20060512
+#define BFD_VERSION_DATE 20060514
 #define BFD_VERSION @bfd_version@
 #define BFD_VERSION_STRING @bfd_version_string@
diff --git a/config.guess b/config.guess
index 7149b1b..c085f4f 100755
--- a/config.guess
+++ b/config.guess
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
 #   Inc.
 
-timestamp='2006-04-26'
+timestamp='2006-05-13'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -989,7 +989,7 @@
 	LIBC=gnulibc1
 	# endif
 	#else
-	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
 	LIBC=gnu
 	#else
 	LIBC=gnuaout
diff --git a/config.sub b/config.sub
index 710f348..4d936e2 100755
--- a/config.sub
+++ b/config.sub
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
 #   Inc.
 
-timestamp='2006-05-12'
+timestamp='2006-05-13'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -1366,6 +1366,9 @@
 # system, and we'll never get to this point.
 
 case $basic_machine in
+        spu-*)
+		os=-elf
+		;;
 	*-acorn)
 		os=-riscix1.2
 		;;
@@ -1375,9 +1378,9 @@
 	arm*-semi)
 		os=-aout
 		;;
-    c4x-* | tic4x-*)
-        os=-coff
-        ;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
 		os=-tops20
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6842b6b..2bc3105 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,93 @@
+2006-05-14  Nick Roberts  <nickrob@snap.net.nz>
+
+	* mi/gdb-mi.el (gdbmi-send): Correct regexp for repeat commands.
+	(gdbmi): Use new variable name gdb-pc-address.
+	(gdbmi-frame-handler):  Use new variable name gdb-pc-address.
+	Check that a match has been found.
+
+2006-05-13  Gaius Mulley  <gaius@glam.ac.uk>
+
+	* m2-lang.h: Added function extern prototypes for
+	m2_is_long_set and get_long_set_bounds.
+	* m2-typeprint.c: Complete replacement.
+	(m2_print_type): Walk the Modula-2 type tree.
+	(m2_type_name): New function.
+	(m2_range): New function.
+	(m2_typedef): New function.
+	(m2_array): New function.
+	(m2_pointer): New function.
+	(m2_ref): New function.
+	(m2_unknown): New function.
+	(m2_union): New function.
+	(m2_procedure): New function.
+	(m2_print_bounds): New function.
+	(m2_short_set): New function.
+	(m2_is_long_set): New function.
+	(m2_get_discrete_bounds): New function.
+	(m2_is_long_set_of_type): New function.
+	(m2_long_set): New function.
+	(m2_record_fields): New function.
+	(m2_enum): New function.
+	* dwarf2read.c: Modified.
+	(read_set_type): New function.
+	(process_die): Call read_set_type.
+	(read_base_type): Modifed.
+	(set_cu_language): Added Modula-2 case clause.
+	* m2-valprint.c: Complete replacement.
+	(print_function_pointer_address): New function.
+	(get_long_set_bounds): New function.
+	(m2_print_long_set): New function.
+	(print_unpacked_pointer): New function.
+	(print_variable_at_address): New function.
+	(m2_val_print): Replaced.
+	* gdb/MAINTAINERS (Write After Approval): Added
+	Gaius Mulley  <gaius@glam.ac.uk>
+
+2006-05-12  Mark Kettenis  <kettenis@gnu.org>
+
+	* ppcnbsd-tdep.h: Update copyright year.  Include <stddef.h>
+	(ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg)
+	(ppcnbsd_fill_fpreg): Remove prototypes.
+	(struct regset): Add forward declaration.
+	(ppcnbsd_gregset, ppcnbsd_fpregset): Extern declarations.
+	* ppcnbsd-tdep.c: Update copyright year.  Include "gdbtypes.h",
+	"regset.h" and "gdb_string.h".  Don't include "breakpoint.h",
+	"value.h", target.h and nbsd-tdep.h".  Reorder includes.
+	(REG_FIXREG_OFFSET, REG_LR_OFFSET, REG_CR_OFFSET, REG_XER_OFFSET)
+	(REG_CTR_OFFSET, REG_PC_OFFSET, SIZEOF_STRUCT_REG)
+	(FPREG_FPR_OFFSET, FPREG_FPSCR_OFFSET, SIZEOF_STRUCT_FPREG):
+	Remove macros.
+	(ppcnbsd_supply_reg, ppcnbsd_fill_reg, ppcnbsd_supply_fpreg)
+	(ppcnbsd_fill_fpreg): Remove functions.
+	(fetch_core_registers, fetch_elfcore_registers): Remove functions.
+	(ppcnbsd_core_fns, ppcnbsd_elfcore_fns): Remove variables.
+	(ppcnbsd_reg_offsets): New variable.
+	(ppcnbsd_gregset, ppcnbsd_fpregset): New variables.
+	(ppcnbsd_sigtramp_cache_init): Deal with new signal trampoline
+	introduced in NetBSD 2.0.
+	(ppcnbsd_sigtramp): Provide complete signal trampoline.
+	(ppcnbsd2_sigtramp): New variable.
+	(ppcnbsd_init_abi): Set svr4_fetch_link_map_offsets to
+	svr4_ilp32_fetch_link_map_offsets.  Set regset_from_core_section.
+	Add ppcnbs2_sigtramp unwinder.
+	(_initialize_ppcnbsd_tdep): Don't use deprecated_add_core_fns.
+	Initialize ppcnbsd_reg_offsets.
+	* ppcnbsd-nat.c: Update copyright year.  Reorder includes.
+	(getregs_supplies): Use regnum instead of regno.
+	(getfpregs_supplies): Likewise.
+	(ppcnbsd_fetch_inferior_registers): Likewise.  Call
+	ppc_supply_gregset and ppc_suppply_fpregset instead of
+	ppcnbsd_supply_reg and ppcnbsd_supply_fpreg
+	(ppcnbsd_store_inferior_registers): Likewise.  Call
+	ppc_collect_gregset and ppc_collect_fpregset instead of
+	ppcnbsd_fill_reg and ppcnbsd_fill_fpreg.
+	(ppcnbsd_supply_pcb): Use `gdb_byte *' instead of `char *'.
+	(_initialize_ppcnbsd_nat): Add some whitespace.
+	* Makefile.in (ppcnbsd-nat.o, ppcnbsd-tdep.o): Update dependencies.
+	* config/powerpc/nbsd.mh (NATDEPFILES): Remove infptrace.o.
+	(NAT_FILE): Remove.
+	* config/powerpc/nbsd.mt (TDEPFILES): Remove nbsd-tdep.o.
+
 2006-05-11  Alfred M. Szmidt  <ams@gnu.org>
 
 	* gnu-nat.c (inf_validate_procs): Don't use lvalue in assignments.
diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS
index 4ed438a..c143a43 100644
--- a/gdb/MAINTAINERS
+++ b/gdb/MAINTAINERS
@@ -503,6 +503,7 @@
 Alan Modra					amodra@bigpond.net.au
 Jason Molenda					jmolenda@apple.com
 Pierre Muller					muller@sources.redhat.com
+Gaius Mulley                                    gaius@glam.ac.uk
 Joseph Myers					joseph@codesourcery.com
 Fernando Nasser					fnasser@redhat.com
 Nathanael Nerode				neroden@gcc.gnu.org
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index a8b58a1..e8cd87a 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2416,13 +2416,13 @@
 ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(gdb_assert_h) \
 	$(gdbcore_h) $(regcache_h) $(bsd_kvm_h) $(ppc_tdep_h) \
 	$(ppcnbsd_tdep_h) $(inf_ptrace_h)
-ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
-	$(target_h) $(breakpoint_h) $(value_h) $(osabi_h) $(ppc_tdep_h) \
-	$(ppcnbsd_tdep_h) $(nbsd_tdep_h) $(tramp_frame_h) $(trad_frame_h) \
-	$(gdb_assert_h) $(solib_svr4_h)
+ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(gdb_types_h) \
+	$(osabi_h) $(regcache_h) $(regset_h) $(trad_frame_h) \
+	$(tramp_frame_h) $(gdb_assert_h) $(gdb_string_h) \
+	$(ppc_tdep_h) $(ppcnbsd_tdep_h) $(solib_svr4_h)
 ppcobsd-nat.o: ppcobsd-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) \
-	$(regcache_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) $(inf_ptrace_h) \
-	$(bsd_kvm_h)
+	$(regcache_h) $(ppc_tdep_h) $(ppcobsd_tdep_h) $(bsd_kvm_h) \
+	$(inf_ptrace_h)
 ppcobsd-tdep.o: ppcobsd-tdep.c $(defs_h) $(arch_utils_h) $(floatformat_h) \
 	$(frame_h) $(frame_unwind_h) $(osabi_h) $(regcache_h) $(regset_h) \
 	$(symtab_h) $(trad_frame_h) $(gdb_assert_h) $(gdb_string_h) \
diff --git a/gdb/config/powerpc/nbsd.mh b/gdb/config/powerpc/nbsd.mh
index 5556886..db0390c 100644
--- a/gdb/config/powerpc/nbsd.mh
+++ b/gdb/config/powerpc/nbsd.mh
@@ -1,5 +1,4 @@
-# Host: PowerPC, running NetBSD
-NATDEPFILES= fork-child.o inf-ptrace.o infptrace.o ppcnbsd-nat.o bsd-kvm.o
-NAT_FILE= config/nm-nbsd.h
+# Host: NetBSD/powerpc
+NATDEPFILES= fork-child.o inf-ptrace.o ppcnbsd-nat.o bsd-kvm.o
 
 LOADLIBES= -lkvm
diff --git a/gdb/config/powerpc/nbsd.mt b/gdb/config/powerpc/nbsd.mt
index 2f50c21..8cdd39d 100644
--- a/gdb/config/powerpc/nbsd.mt
+++ b/gdb/config/powerpc/nbsd.mt
@@ -1,6 +1,6 @@
-# Target: PowerPC, running NetBSD
-TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o nbsd-tdep.o corelow.o \
-	solib.o solib-svr4.o
+# Target: NetBSD/powerpc
+TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcnbsd-tdep.o \
+	corelow.o solib.o solib-svr4.o
 DEPRECATED_TM_FILE= tm-ppc-eabi.h
 
 SIM_OBS = remote-sim.o
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index f759123..cdf4622 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,12 @@
+2006-05-14  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* gdb.texinfo (General Query Packets): Recommend not starting
+	new packets with qC and clarify.
+
+2006-05-13  Gaius Mulley  <gaius@glam.ac.uk>
+
+	* gdb.texinfo (M2 Types): New section.
+
 2006-05-10  Daniel Jacobowitz  <dan@codesourcery.com>
 
 	* agentexpr.texi: Add a copyright and license notice.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e2b986a..422d63e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -9471,6 +9471,7 @@
 * M2 Operators::                Built-in operators
 * Built-In Func/Proc::          Built-in functions and procedures
 * M2 Constants::                Modula-2 constants
+* M2 Types::                    Modula-2 types
 * M2 Defaults::                 Default settings for Modula-2
 * Deviations::                  Deviations from standard Modula-2
 * M2 Checks::                   Modula-2 type and range checks
@@ -9595,7 +9596,7 @@
 @end table
 
 @quotation
-@emph{Warning:} Sets and their operations are not yet supported, so @value{GDBN}
+@emph{Warning:} Set expressions and their operations are not yet supported, so @value{GDBN}
 treats the use of the operator @code{IN}, or the use of operators
 @code{+}, @code{-}, @code{*}, @code{/}, @code{=}, , @code{<>}, @code{#},
 @code{<=}, and @code{>=} on sets as an error.
@@ -9764,6 +9765,170 @@
 Set constants are not yet supported.
 @end itemize
 
+@node M2 Types
+@subsubsection Modula-2 Types
+@cindex Modula-2 types
+
+Currently @value{GDBN} can print the following data types in Modula-2
+syntax: array types, record types, set types, pointer types, procedure
+types, enumerated types, subrange types and base types.  You can also
+print the contents of variables declared using these type.
+This section gives a number of simple source code examples together with
+sample @value{GDBN} sessions.
+
+The first example contains the following section of code:
+
+@smallexample
+VAR
+   s: SET OF CHAR ;
+   r: [20..40] ;
+@end smallexample
+
+@noindent
+and you can request @value{GDBN} to interrogate the type and value of
+@code{r} and @code{s}.
+
+@smallexample
+(@value{GDBP}) print s
+@{'A'..'C', 'Z'@}
+(@value{GDBP}) ptype s
+SET OF CHAR
+(@value{GDBP}) print r
+21
+(@value{GDBP}) ptype r
+[20..40]
+@end smallexample
+
+@noindent
+Likewise if your source code declares @code{s} as:
+
+@smallexample
+VAR
+   s: SET ['A'..'Z'] ;
+@end smallexample
+
+@noindent
+then you may query the type of @code{s} by:
+
+@smallexample
+(@value{GDBP}) ptype s
+type = SET ['A'..'Z']
+@end smallexample
+
+@noindent
+Note that at present you cannot interactively manipulate set
+expressions using the debugger.
+
+The following example shows how you might declare an array in Modula-2
+and how you can interact with @value{GDBN} to print its type and contents:
+
+@smallexample
+VAR
+   s: ARRAY [-10..10] OF CHAR ;
+@end smallexample
+
+@smallexample
+(@value{GDBP}) ptype s
+ARRAY [-10..10] OF CHAR
+@end smallexample
+
+Note that the array handling is not yet complete and although the type
+is printed correctly, expression handling still assumes that all
+arrays have a lower bound of zero and not @code{-10} as in the example
+above.  Unbounded arrays are also not yet recognized in @value{GDBN}.
+
+Here are some more type related Modula-2 examples:
+
+@smallexample
+TYPE
+   colour = (blue, red, yellow, green) ;
+   t = [blue..yellow] ;
+VAR
+   s: t ;
+BEGIN
+   s := blue ;
+@end smallexample
+
+@noindent
+The @value{GDBN} interaction shows how you can query the data type
+and value of a variable.
+
+@smallexample
+(@value{GDBP}) print s
+$1 = blue
+(@value{GDBP}) ptype t
+type = [blue..yellow]
+@end smallexample
+
+@noindent
+In this example a Modula-2 array is declared and its contents
+displayed.  Observe that the contents are written in the same way as
+their @code{C} counterparts.
+
+@smallexample
+VAR
+   s: ARRAY [1..5] OF CARDINAL ;
+BEGIN
+   s[1] := 1 ;
+@end smallexample
+
+@smallexample
+(@value{GDBP}) print s
+$1 = @{1, 0, 0, 0, 0@}
+(@value{GDBP}) ptype s
+type = ARRAY [1..5] OF CARDINAL
+@end smallexample
+
+The Modula-2 language interface to @value{GDBN} also understands
+pointer types as shown in this example:
+
+@smallexample
+VAR
+   s: POINTER TO ARRAY [1..5] OF CARDINAL ;
+BEGIN
+   NEW(s) ;
+   s^[1] := 1 ;
+@end smallexample
+
+@noindent
+and you can request that @value{GDBN} describes the type of @code{s}.
+
+@smallexample
+(@value{GDBP}) ptype s
+type = POINTER TO ARRAY [1..5] OF CARDINAL
+@end smallexample
+
+@value{GDBN} handles compound types as we can see in this example.
+Here we combine array types, record types, pointer types and subrange
+types:
+
+@smallexample
+TYPE
+   foo = RECORD
+            f1: CARDINAL ;
+            f2: CHAR ;
+            f3: myarray ;
+         END ;
+
+   myarray = ARRAY myrange OF CARDINAL ;
+   myrange = [-2..2] ;
+VAR
+   s: POINTER TO ARRAY myrange OF foo ;
+@end smallexample
+
+@noindent
+and you can ask @value{GDBN} to describe the type of @code{s} as shown
+below.
+
+@smallexample
+(@value{GDBP}) ptype s
+type = POINTER TO ARRAY [-2..2] OF foo = RECORD
+    f1 : CARDINAL;
+    f2 : CHAR;
+    f3 : ARRAY [-2..2] OF CARDINAL;
+END 
+@end smallexample
+
 @node M2 Defaults
 @subsubsection Modula-2 defaults
 @cindex Modula-2 defaults
@@ -23101,11 +23266,14 @@
 The name of a query or set packet should be separated from any
 parameters by a @samp{:}; the parameters themselves should be
 separated by @samp{,} or @samp{;}.  Stubs must be careful to match the
-full packet name, in case packet names have common prefixes.  New
-packets should not begin with @samp{qP} or @samp{qL}@footnote{The
-@samp{qP} and @samp{qL} packets predate these conventions, and don't
-have any terminator for the packet name; we suspect they are in
-widespread use in places that are difficult to upgrade.}.
+full packet name, and check for a separator or the end of the packet,
+in case two packet names share a common prefix.  New packets should not begin
+with @samp{qC}, @samp{qP}, or @samp{qL}@footnote{The @samp{qP} and @samp{qL}
+packets predate these conventions, and have arguments without any terminator
+for the packet name; we suspect they are in widespread use in places that
+are difficult to upgrade.  The @samp{qC} packet has no arguments, but some
+existing stubs (e.g.@: RedBoot) are known to not check for the end of the
+packet.}.
 
 Like the descriptions of the other packets, each description here
 has a template showing the packet's overall syntax, followed by an
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 0881e3d..31b0ae0 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1,7 +1,7 @@
 /* DWARF 2 debugging format support for GDB.
 
-   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006
+   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+                 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
@@ -1073,6 +1073,9 @@
 
 static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
 
+static void read_set_type (struct die_info *, struct dwarf2_cu *);
+
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
@@ -2662,6 +2665,9 @@
     case DW_TAG_subroutine_type:
       read_subroutine_type (die, cu);
       break;
+    case DW_TAG_set_type:
+      read_set_type (die, cu);
+      break;
     case DW_TAG_array_type:
       read_array_type (die, cu);
       break;
@@ -4240,6 +4246,15 @@
     };
 }
 
+/* Extract all information from a DW_TAG_set_type DIE and put it in
+   the DIE's type field. */
+
+static void
+read_set_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+  if (die->type == NULL)
+    die->type = create_set_type ((struct type *) NULL, die_type (die, cu));
+}
 
 /* First cut: install each common block member as a global variable.  */
 
@@ -4728,10 +4743,17 @@
 	  code = TYPE_CODE_FLT;
 	  break;
 	case DW_ATE_signed:
-	case DW_ATE_signed_char:
 	  break;
 	case DW_ATE_unsigned:
-	case DW_ATE_unsigned_char:
+	  type_flags |= TYPE_FLAG_UNSIGNED;
+	  break;
+	case DW_ATE_signed_char:
+	  if (cu->language == language_m2)
+	    code = TYPE_CODE_CHAR;
+	  break;
+ 	case DW_ATE_unsigned_char:
+	  if (cu->language == language_m2)
+	    code = TYPE_CODE_CHAR;
 	  type_flags |= TYPE_FLAG_UNSIGNED;
 	  break;
 	default:
@@ -6168,10 +6190,12 @@
     case DW_LANG_Ada95:
       cu->language = language_ada;
       break;
+    case DW_LANG_Modula2:
+      cu->language = language_m2;
+      break;
     case DW_LANG_Cobol74:
     case DW_LANG_Cobol85:
     case DW_LANG_Pascal83:
-    case DW_LANG_Modula2:
     default:
       cu->language = language_minimal;
       break;
@@ -6961,6 +6985,7 @@
 	case DW_TAG_class_type:
 	case DW_TAG_structure_type:
 	case DW_TAG_union_type:
+	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
@@ -7290,6 +7315,9 @@
     case DW_TAG_array_type:
       read_array_type (die, cu);
       break;
+    case DW_TAG_set_type:
+      read_set_type (die, cu);
+      break;
     case DW_TAG_pointer_type:
       read_tag_pointer_type (die, cu);
       break;
diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h
index a57cef0..294707a 100644
--- a/gdb/m2-lang.h
+++ b/gdb/m2-lang.h
@@ -27,6 +27,11 @@
 extern void m2_print_type (struct type *, char *, struct ui_file *, int,
 			   int);
 
+extern int m2_is_long_set (struct type *type);
+
 extern int m2_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
 			 struct ui_file *, int, int, int,
 			 enum val_prettyprint);
+
+extern int get_long_set_bounds (struct type *type, LONGEST *low,
+				LONGEST *high);
diff --git a/gdb/m2-typeprint.c b/gdb/m2-typeprint.c
index 7763d32..160305c 100644
--- a/gdb/m2-typeprint.c
+++ b/gdb/m2-typeprint.c
@@ -1,5 +1,6 @@
 /* Support for printing Modula 2 types for GDB, the GNU debugger.
-   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1995, 2000
+   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1995, 2000, 2001,
+                 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -20,22 +21,554 @@
    Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
+#include "gdb_obstack.h"
 #include "bfd.h"		/* Binary File Description */
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "expression.h"
 #include "value.h"
 #include "gdbcore.h"
-#include "target.h"
 #include "m2-lang.h"
+#include "target.h"
+#include "language.h"
+#include "demangle.h"
+#include "c-lang.h"
+#include "typeprint.h"
+#include "cp-abi.h"
+
+#include "gdb_string.h"
 #include <errno.h>
 
+static void m2_print_bounds (struct type *type,
+			     struct ui_file *stream, int show, int level,
+			     int print_high);
+
+static void m2_typedef (struct type *, struct ui_file *, int, int);
+static void m2_array (struct type *, struct ui_file *, int, int);
+static void m2_pointer (struct type *, struct ui_file *, int, int);
+static void m2_ref (struct type *, struct ui_file *, int, int);
+static void m2_procedure (struct type *, struct ui_file *, int, int);
+static void m2_union (struct type *, struct ui_file *);
+static void m2_enum (struct type *, struct ui_file *, int, int);
+static void m2_range (struct type *, struct ui_file *, int, int);
+static void m2_type_name (struct type *type, struct ui_file *stream);
+static void m2_short_set (struct type *type, struct ui_file *stream,
+			  int show, int level);
+static int m2_long_set (struct type *type, struct ui_file *stream,
+			int show, int level);
+static void m2_record_fields (struct type *type, struct ui_file *stream,
+			      int show, int level);
+static void m2_unknown (const char *s, struct type *type,
+			struct ui_file *stream, int show, int level);
+
+int m2_is_long_set (struct type *type);
+int m2_is_long_set_of_type (struct type *type, struct type **of_type);
+
+
 void
 m2_print_type (struct type *type, char *varstring, struct ui_file *stream,
 	       int show, int level)
 {
-  extern void c_print_type (struct type *, char *, struct ui_file *, int,
-			    int);
+  enum type_code code;
+  int demangled_args;
 
-  c_print_type (type, varstring, stream, show, level);	/* FIXME */
+  CHECK_TYPEDEF (type);
+  code = TYPE_CODE (type);
+
+  QUIT;
+
+  wrap_here ("    ");
+  if (type == NULL)
+    {
+      fputs_filtered (_("<type unknown>"), stream);
+      return;
+    }
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_SET:
+      m2_short_set(type, stream, show, level);
+      break;
+
+    case TYPE_CODE_STRUCT:
+      if (m2_long_set (type, stream, show, level))
+	break;
+      m2_record_fields (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_TYPEDEF:
+      m2_typedef (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_ARRAY:
+      m2_array (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_PTR:
+      m2_pointer (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_REF:
+      m2_ref (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_MEMBER:
+      m2_unknown (_("member"), type, stream, show, level);
+      break;
+
+    case TYPE_CODE_METHOD:
+      m2_unknown (_("method"), type, stream, show, level);
+      break;
+
+    case TYPE_CODE_FUNC:
+      m2_procedure (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_UNION:
+      m2_union (type, stream);
+      break;
+
+    case TYPE_CODE_ENUM:
+      m2_enum (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_VOID:
+      break;
+
+    case TYPE_CODE_UNDEF:
+      /* i18n: Do not translate the "struct" part! */
+      m2_unknown (_("undef"), type, stream, show, level);
+      break;
+
+    case TYPE_CODE_ERROR:
+      m2_unknown (_("error"), type, stream, show, level);
+      break;
+
+    case TYPE_CODE_RANGE:
+      m2_range (type, stream, show, level);
+      break;
+
+    case TYPE_CODE_TEMPLATE:
+      break;
+
+    default:
+      m2_type_name (type, stream);
+      break;
+    }
+}
+
+/*
+ *  m2_type_name - if a, type, has a name then print it.
+ */
+
+void
+m2_type_name (struct type *type, struct ui_file *stream)
+{
+  if (TYPE_NAME (type) != NULL)
+    fputs_filtered (TYPE_NAME (type), stream);
+}
+
+/*
+ *  m2_range - displays a Modula-2 subrange type.
+ */
+
+void
+m2_range (struct type *type, struct ui_file *stream, int show,
+	  int level)
+{
+  if (TYPE_HIGH_BOUND (type) == TYPE_LOW_BOUND (type))
+    m2_print_type (TYPE_DOMAIN_TYPE (type), "", stream, show, level);
+  else
+    {
+      struct type *target = TYPE_TARGET_TYPE (type);
+
+      fprintf_filtered (stream, "[");
+      print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
+      fprintf_filtered (stream, "..");
+      print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
+      fprintf_filtered (stream, "]");
+    }
+}
+
+static void
+m2_typedef (struct type *type, struct ui_file *stream, int show,
+	    int level)
+{
+  if (TYPE_NAME (type) != NULL)
+    {
+      fputs_filtered (TYPE_NAME (type), stream);
+      fputs_filtered (" = ", stream);
+    }
+  m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
+}
+
+/*
+ *  m2_array - prints out a Modula-2 ARRAY ... OF type
+ */
+
+static void m2_array (struct type *type, struct ui_file *stream,
+		      int show, int level)
+{
+  fprintf_filtered (stream, "ARRAY [");
+  if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
+      && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED)
+    {
+      if (TYPE_INDEX_TYPE (type) != 0)
+	{
+	  m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 0);
+	  fprintf_filtered (stream, "..");
+	  m2_print_bounds (TYPE_INDEX_TYPE (type), stream, show, -1, 1);
+	}
+      else
+	fprintf_filtered (stream, "%d",
+			  (TYPE_LENGTH (type)
+			   / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
+    }
+  fprintf_filtered (stream, "] OF ");
+  m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
+}
+
+static void
+m2_pointer (struct type *type, struct ui_file *stream, int show,
+	    int level)
+{
+  if (TYPE_CONST (type))
+    fprintf_filtered (stream, "[...] : ");
+  else
+    fprintf_filtered (stream, "POINTER TO ");
+
+  m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
+}
+
+static void
+m2_ref (struct type *type, struct ui_file *stream, int show,
+	int level)
+{
+  fprintf_filtered (stream, "VAR");
+  m2_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
+}
+
+static void
+m2_unknown (const char *s, struct type *type, struct ui_file *stream,
+	    int show, int level)
+{
+  fprintf_filtered (stream, "%s %s", s, _("is unknown"));
+}
+
+static void m2_union (struct type *type, struct ui_file *stream)
+{
+  fprintf_filtered (stream, "union");
+}
+
+static void
+m2_procedure (struct type *type, struct ui_file *stream,
+	      int show, int level)
+{
+  fprintf_filtered (stream, "PROCEDURE ");
+  m2_type_name (type, stream);
+  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+    {
+      int i, len = TYPE_NFIELDS (type);
+
+      fprintf_filtered (stream, " (");
+      for (i = 0; i < len; i++)
+	{
+	  if (i > 0)
+	    {
+	      fputs_filtered (", ", stream);
+	      wrap_here ("    ");
+	    }
+	  m2_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+	}
+      if (TYPE_TARGET_TYPE (type) != NULL)
+	{
+	  fprintf_filtered (stream, " : ");
+	  m2_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0);
+	}
+    }
+}
+
+static void
+m2_print_bounds (struct type *type,
+		 struct ui_file *stream, int show, int level,
+		 int print_high)
+{
+  struct type *target = TYPE_TARGET_TYPE (type);
+
+  if (target == NULL)
+    target = builtin_type_int;
+
+  if (TYPE_NFIELDS(type) == 0)
+    return;
+
+  if (print_high)
+    print_type_scalar (target, TYPE_HIGH_BOUND (type), stream);
+  else
+    print_type_scalar (target, TYPE_LOW_BOUND (type), stream);
+}
+
+static void
+m2_short_set (struct type *type, struct ui_file *stream, int show, int level)
+{
+  fprintf_filtered(stream, "SET [");
+  m2_print_bounds (TYPE_INDEX_TYPE (type), stream,
+		   show - 1, level, 0);
+
+  fprintf_filtered(stream, "..");
+  m2_print_bounds (TYPE_INDEX_TYPE (type), stream,
+		   show - 1, level, 1);
+  fprintf_filtered(stream, "]");
+}
+
+int
+m2_is_long_set (struct type *type)
+{
+  LONGEST previous_high = 0;  /* unnecessary initialization
+				 keeps gcc -Wall happy */
+  int len, i;
+  struct type *range;
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    {
+
+      /*
+       *  check if all fields of the RECORD are consecutive sets
+       */
+      len = TYPE_NFIELDS (type);
+      for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+	{
+	  if (TYPE_FIELD_TYPE (type, i) == NULL)
+	    return 0;
+	  if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) != TYPE_CODE_SET)
+	    return 0;
+	  if (TYPE_FIELD_NAME (type, i) != NULL
+	      && (strcmp (TYPE_FIELD_NAME (type, i), "") != 0))
+	    return 0;
+	  range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i));
+	  if ((i > TYPE_N_BASECLASSES (type))
+	      && previous_high + 1 != TYPE_LOW_BOUND (range))
+	    return 0;
+	  previous_high = TYPE_HIGH_BOUND (range);
+	}
+      return len>0;
+    }
+  return 0;
+}
+
+/*
+ *  m2_get_discrete_bounds - a wrapper for get_discrete_bounds which
+ *                           understands that CHARs might be signed.
+ *                           This should be integrated into gdbtypes.c
+ *                           inside get_discrete_bounds.
+ */
+
+int
+m2_get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
+{
+  CHECK_TYPEDEF (type);
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_CHAR:
+      if (TYPE_LENGTH (type) < sizeof (LONGEST))
+	{
+	  if (!TYPE_UNSIGNED (type))
+	    {
+	      *lowp = -(1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
+	      *highp = -*lowp - 1;
+	      return 0;
+	    }
+	}
+      /* fall through */
+    default:
+      return get_discrete_bounds (type, lowp, highp);
+    }
+}
+
+/*
+ *  m2_is_long_set_of_type - returns TRUE if the long set was declared as
+ *                           SET OF <oftype> of_type is assigned to the
+ *                           subtype.
+ */
+
+int
+m2_is_long_set_of_type (struct type *type, struct type **of_type)
+{
+  int len, i;
+  struct type *range;
+  struct type *target;
+  LONGEST l1, l2;
+  LONGEST h1, h2;
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    {
+      len = TYPE_NFIELDS (type);
+      i = TYPE_N_BASECLASSES (type);
+      if (len == 0)
+	return 0;
+      range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i));
+      target = TYPE_TARGET_TYPE (range);
+      if (target == NULL)
+	target = builtin_type_int;
+
+      l1 = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)));
+      h1 = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1)));
+      *of_type = target;
+      if (m2_get_discrete_bounds (target, &l2, &h2) >= 0)
+	return (l1 == l2 && h1 == h2);
+      error (_("long_set failed to find discrete bounds for its subtype"));
+      return 0;
+    }
+  error (_("expecting long_set"));
+  return 0;
+}
+
+static int
+m2_long_set (struct type *type, struct ui_file *stream, int show, int level)
+{
+  struct type *index_type;
+  struct type *range_type;
+  struct type *of_type;
+  int i;
+  int len = TYPE_NFIELDS (type);
+  LONGEST low;
+  LONGEST high;
+
+  if (m2_is_long_set (type))
+    {
+      if (TYPE_TAG_NAME (type) != NULL)
+	{
+	  fputs_filtered (TYPE_TAG_NAME (type), stream);
+	  if (show == 0)
+	    return 1;
+	}
+      else if (TYPE_NAME (type) != NULL)
+	{
+	  fputs_filtered (TYPE_NAME (type), stream);
+	  if (show == 0)
+	    return 1;
+	}
+
+      if (TYPE_TAG_NAME (type) != NULL || TYPE_NAME (type) != NULL)
+	fputs_filtered (" = ", stream);
+
+      if (get_long_set_bounds (type, &low, &high))
+	{
+	  fprintf_filtered(stream, "SET OF ");
+	  i = TYPE_N_BASECLASSES (type);
+	  if (m2_is_long_set_of_type (type, &of_type))
+	    m2_print_type (of_type, "", stream, show - 1, level);
+	  else
+	    {
+	      fprintf_filtered(stream, "[");
+	      m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)),
+			       stream, show - 1, level, 0);
+
+	      fprintf_filtered(stream, "..");
+
+	      m2_print_bounds (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, len-1)),
+			       stream, show - 1, level, 1);
+	      fprintf_filtered(stream, "]");
+	    }
+	}
+      else
+	/* i18n: Do not translate the "SET OF" part! */
+	fprintf_filtered(stream, _("SET OF <unknown>"));
+
+      return 1;
+    }
+  return 0;
+}
+
+void
+m2_record_fields (struct type *type, struct ui_file *stream, int show,
+		  int level)
+{
+  /* Print the tag if it exists. 
+   */
+  if (TYPE_TAG_NAME (type) != NULL)
+    {
+      if (strncmp (TYPE_TAG_NAME (type), "$$", 2) != 0)
+	{
+	  fputs_filtered (TYPE_TAG_NAME (type), stream);
+	  if (show > 0)
+	    fprintf_filtered (stream, " = ");
+	}
+    }
+  wrap_here ("    ");
+  if (show < 0)
+    {
+      if (TYPE_CODE (type) == DECLARED_TYPE_STRUCT)
+	fprintf_filtered (stream, "RECORD ... END ");
+      else if (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_UNION)
+	fprintf_filtered (stream, "CASE ... END ");
+    }
+  else if (show > 0)
+    {
+      if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+	fprintf_filtered (stream, "RECORD\n");
+      else if (TYPE_CODE (type) == TYPE_CODE_UNION)
+	/* i18n: Do not translate "CASE" and "OF" */
+	fprintf_filtered (stream, _("CASE <variant> OF\n"));
+      int i;
+      int len = TYPE_NFIELDS (type);
+
+      for (i = TYPE_N_BASECLASSES (type); i < len; i++)
+	{
+	  QUIT;
+
+	  print_spaces_filtered (level + 4, stream);
+	  fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+	  fputs_filtered (" : ", stream);
+	  m2_print_type (TYPE_FIELD_TYPE (type, i),
+			 "",
+			 stream, 0, level + 4);
+	  if (TYPE_FIELD_PACKED (type, i))
+	    {
+	      /* It is a bitfield.  This code does not attempt
+		 to look at the bitpos and reconstruct filler,
+		 unnamed fields.  This would lead to misleading
+		 results if the compiler does not put out fields
+		 for such things (I don't know what it does).  */
+	      fprintf_filtered (stream, " : %d",
+				TYPE_FIELD_BITSIZE (type, i));
+	    }
+	  fprintf_filtered (stream, ";\n");
+	}
+      
+      fprintfi_filtered (level, stream, "END ");
+    }
+}
+
+void
+m2_enum (struct type *type, struct ui_file *stream, int show, int level)
+{
+  int lastval, i, len;
+
+  if (show < 0)
+    {
+      /* If we just printed a tag name, no need to print anything else.  */
+      if (TYPE_TAG_NAME (type) == NULL)
+	fprintf_filtered (stream, "(...)");
+    }
+  else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+    {
+      fprintf_filtered (stream, "(");
+      len = TYPE_NFIELDS (type);
+      lastval = 0;
+      for (i = 0; i < len; i++)
+	{
+	  QUIT;
+	  if (i > 0)
+	    fprintf_filtered (stream, ", ");
+	  wrap_here ("    ");
+	  fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+	  if (lastval != TYPE_FIELD_BITPOS (type, i))
+	    {
+	      fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i));
+	      lastval = TYPE_FIELD_BITPOS (type, i);
+	    }
+	  lastval++;
+	}
+      fprintf_filtered (stream, ")");
+    }
 }
diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c
index 7b38dc9..579ea8b 100644
--- a/gdb/m2-valprint.c
+++ b/gdb/m2-valprint.c
@@ -1,7 +1,8 @@
 /* Support for printing Modula 2 values for GDB, the GNU debugger.
 
-   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1996, 1998, 2000, 2005 Free
-   Software Foundation, Inc.
+   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1996, 1998,
+                 2000, 2005, 2006
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -23,14 +24,562 @@
 #include "defs.h"
 #include "symtab.h"
 #include "gdbtypes.h"
-#include "m2-lang.h"
+#include "expression.h"
+#include "value.h"
+#include "valprint.h"
+#include "language.h"
+#include "typeprint.h"
 #include "c-lang.h"
+#include "m2-lang.h"
+#include "target.h"
+
+int print_unpacked_pointer (struct type *type,
+			    CORE_ADDR address, CORE_ADDR addr,
+			    int format, struct ui_file *stream);
+
+
+/* Print function pointer with inferior address ADDRESS onto stdio
+   stream STREAM.  */
+
+static void
+print_function_pointer_address (CORE_ADDR address, struct ui_file *stream)
+{
+  CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+							    address,
+							    &current_target);
+
+  /* If the function pointer is represented by a description, print the
+     address of the description.  */
+  if (addressprint && func_addr != address)
+    {
+      fputs_filtered ("@", stream);
+      fputs_filtered (paddress (address), stream);
+      fputs_filtered (": ", stream);
+    }
+  print_address_demangle (func_addr, stream, demangle);
+}
+
+/*
+ *  get_long_set_bounds - assigns the bounds of the long set to low and high.
+ */
+
+int
+get_long_set_bounds (struct type *type, LONGEST *low, LONGEST *high)
+{
+  int len, i;
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    {
+      len = TYPE_NFIELDS (type);
+      i = TYPE_N_BASECLASSES (type);
+      if (len == 0)
+	return 0;
+      *low = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, i)));
+      *high = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type,
+								 len-1)));
+      return 1;
+    }
+  error (_("expecting long_set"));
+  return 0;
+}
+
+static void
+m2_print_long_set (struct type *type, const gdb_byte *valaddr,
+		   int embedded_offset, CORE_ADDR address,
+		   struct ui_file *stream, int format,
+		   enum val_prettyprint pretty)
+{
+  int empty_set        = 1;
+  int element_seen     = 0;
+  LONGEST previous_low = 0;
+  LONGEST previous_high= 0;
+  LONGEST i, low_bound, high_bound;
+  LONGEST field_low, field_high;
+  struct type *range;
+  int len, field;
+  struct type *target;
+  int bitval;
+
+  CHECK_TYPEDEF (type);
+
+  fprintf_filtered (stream, "{");
+  len = TYPE_NFIELDS (type);
+  if (get_long_set_bounds (type, &low_bound, &high_bound))
+    {
+      field = TYPE_N_BASECLASSES (type);
+      range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, field));
+    }
+  else
+    {
+      fprintf_filtered (stream, " %s }", _("<unknown bounds of set>"));
+      return;
+    }
+
+  target = TYPE_TARGET_TYPE (range);
+  if (target == NULL)
+    target = builtin_type_int;
+
+  if (get_discrete_bounds (range, &field_low, &field_high) >= 0)
+    {
+      for (i = low_bound; i <= high_bound; i++)
+	{
+	  bitval = value_bit_index (TYPE_FIELD_TYPE (type, field),
+				    (TYPE_FIELD_BITPOS (type, field) / 8) +
+				    valaddr + embedded_offset, i);
+	  if (bitval < 0)
+	    error (_("bit test is out of range"));
+	  else if (bitval > 0)
+	    {
+	      previous_high = i;
+	      if (! element_seen)
+		{
+		  if (! empty_set)
+		    fprintf_filtered (stream, ", ");
+		  print_type_scalar (target, i, stream);
+		  empty_set    = 0;
+		  element_seen = 1;
+		  previous_low = i;
+		}
+	    }
+	  else
+	    {
+	      /* bit is not set */
+	      if (element_seen)
+		{
+		  if (previous_low+1 < previous_high)
+		    fprintf_filtered (stream, "..");
+		  if (previous_low+1 < previous_high)
+		    print_type_scalar (target, previous_high, stream);
+		  element_seen = 0;
+		}
+	    }
+	  if (i == field_high)
+	    {
+	      field++;
+	      if (field == len)
+		break;
+	      range = TYPE_INDEX_TYPE (TYPE_FIELD_TYPE (type, field));
+	      if (get_discrete_bounds (range, &field_low, &field_high) < 0)
+		break;
+	      target = TYPE_TARGET_TYPE (range);
+	      if (target == NULL)
+		target = builtin_type_int;
+	    }
+	}
+      if (element_seen)
+	{
+	  if (previous_low+1 < previous_high)
+	    {
+	      fprintf_filtered (stream, "..");
+	      print_type_scalar (target, previous_high, stream);
+	    }
+	  element_seen = 0;
+	}
+      fprintf_filtered (stream, "}");
+    }
+}
+
+int
+print_unpacked_pointer (struct type *type,
+			CORE_ADDR address, CORE_ADDR addr,
+			int format, struct ui_file *stream)
+{
+  struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
+
+  if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+    {
+      /* Try to print what function it points to.  */
+      print_function_pointer_address (addr, stream);
+      /* Return value is irrelevant except for string pointers.  */
+      return 0;
+    }
+
+  if (addressprint && format != 's')
+    fputs_filtered (paddress (address), stream);
+
+  /* For a pointer to char or unsigned char, also print the string
+     pointed to, unless pointer is null.  */
+
+  if (TYPE_LENGTH (elttype) == 1
+      && TYPE_CODE (elttype) == TYPE_CODE_INT
+      && (format == 0 || format == 's')
+      && addr != 0)
+      return val_print_string (addr, -1, TYPE_LENGTH (elttype), stream);
+  
+  return 0;
+}
+
+static void
+print_variable_at_address (struct type *type, const gdb_byte *valaddr,
+			   struct ui_file *stream, int format,
+			   int deref_ref, int recurse,
+			   enum val_prettyprint pretty)
+{
+  CORE_ADDR addr = unpack_pointer (type, valaddr);
+  struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
+
+  fprintf_filtered (stream, "[");
+  fputs_filtered (paddress (addr), stream);
+  fprintf_filtered (stream, "] : ");
+  
+  if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
+    {
+      struct value *deref_val =
+	value_at
+	(TYPE_TARGET_TYPE (type),
+	 unpack_pointer (lookup_pointer_type (builtin_type_void),
+			 valaddr));
+      common_val_print (deref_val, stream, format, deref_ref,
+			recurse, pretty);
+    }
+  else
+    fputs_filtered ("???", stream);
+}
+
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+   the inferior at address ADDRESS, onto stdio stream STREAM according to
+   FORMAT (a letter or 0 for natural format).  The data at VALADDR is in
+   target byte order.
+
+   If the data are a string pointer, returns the number of string characters
+   printed.
+
+   If DEREF_REF is nonzero, then dereference references, otherwise just print
+   them like pointers.
+
+   The PRETTY parameter controls prettyprinting.  */
 
 int
 m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
 	      CORE_ADDR address, struct ui_file *stream, int format,
 	      int deref_ref, int recurse, enum val_prettyprint pretty)
 {
-  return (c_val_print (type, valaddr, 0, address, stream, format, deref_ref,
-		       recurse, pretty));
+  unsigned int i = 0;	/* Number of characters printed */
+  unsigned len;
+  struct type *elttype;
+  unsigned eltlen;
+  int length_pos, length_size, string_pos;
+  int char_size;
+  LONGEST val;
+  CORE_ADDR addr;
+
+  CHECK_TYPEDEF (type);
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+	{
+	  elttype = check_typedef (TYPE_TARGET_TYPE (type));
+	  eltlen = TYPE_LENGTH (elttype);
+	  len = TYPE_LENGTH (type) / eltlen;
+	  if (prettyprint_arrays)
+	    print_spaces_filtered (2 + 2 * recurse, stream);
+	  /* For an array of chars, print with string syntax.  */
+	  if (eltlen == 1 &&
+	      ((TYPE_CODE (elttype) == TYPE_CODE_INT)
+	       || ((current_language->la_language == language_m2)
+		   && (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
+	      && (format == 0 || format == 's'))
+	    {
+	      /* If requested, look for the first null char and only print
+	         elements up to it.  */
+	      if (stop_print_at_null)
+		{
+		  unsigned int temp_len;
+
+		  /* Look for a NULL char. */
+		  for (temp_len = 0;
+		       (valaddr + embedded_offset)[temp_len]
+			 && temp_len < len && temp_len < print_max;
+		       temp_len++);
+		  len = temp_len;
+		}
+
+	      LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0);
+	      i = len;
+	    }
+	  else
+	    {
+	      fprintf_filtered (stream, "{");
+	      val_print_array_elements (type, valaddr + embedded_offset,
+					address, stream, format, deref_ref,
+					recurse, pretty, 0);
+	      fprintf_filtered (stream, "}");
+	    }
+	  break;
+	}
+      /* Array of unspecified length: treat like pointer to first elt.  */
+      print_unpacked_pointer (type, address, address, format, stream);
+      break;
+
+    case TYPE_CODE_PTR:
+      if (TYPE_CONST (type))
+	print_variable_at_address (type, valaddr + embedded_offset,
+				   stream, format, deref_ref, recurse,
+				   pretty);
+      else if (format && format != 's')
+	print_scalar_formatted (valaddr + embedded_offset, type, format,
+				0, stream);
+      else
+	{
+	  addr = unpack_pointer (type, valaddr + embedded_offset);
+	  print_unpacked_pointer (type, addr, address, format, stream);
+	}
+      break;
+
+    case TYPE_CODE_MEMBER:
+      error (_("not implemented: member type in m2_val_print"));
+      break;
+
+    case TYPE_CODE_REF:
+      elttype = check_typedef (TYPE_TARGET_TYPE (type));
+      if (addressprint)
+	{
+	  CORE_ADDR addr
+	    = extract_typed_address (valaddr + embedded_offset, type);
+	  fprintf_filtered (stream, "@");
+	  fputs_filtered (paddress (addr), stream);
+	  if (deref_ref)
+	    fputs_filtered (": ", stream);
+	}
+      /* De-reference the reference.  */
+      if (deref_ref)
+	{
+	  if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
+	    {
+	      struct value *deref_val =
+		value_at
+		(TYPE_TARGET_TYPE (type),
+		 unpack_pointer (lookup_pointer_type (builtin_type_void),
+				 valaddr + embedded_offset));
+	      common_val_print (deref_val, stream, format, deref_ref,
+				recurse, pretty);
+	    }
+	  else
+	    fputs_filtered ("???", stream);
+	}
+      break;
+
+    case TYPE_CODE_UNION:
+      if (recurse && !unionprint)
+	{
+	  fprintf_filtered (stream, "{...}");
+	  break;
+	}
+      /* Fall through.  */
+    case TYPE_CODE_STRUCT:
+      if (m2_is_long_set (type))
+	m2_print_long_set (type, valaddr, embedded_offset, address,
+			   stream, format, pretty);
+      else
+	cp_print_value_fields (type, type, valaddr, embedded_offset,
+			       address, stream, format,
+			       recurse, pretty, NULL, 0);
+      break;
+
+    case TYPE_CODE_ENUM:
+      if (format)
+	{
+	  print_scalar_formatted (valaddr + embedded_offset, type,
+				  format, 0, stream);
+	  break;
+	}
+      len = TYPE_NFIELDS (type);
+      val = unpack_long (type, valaddr + embedded_offset);
+      for (i = 0; i < len; i++)
+	{
+	  QUIT;
+	  if (val == TYPE_FIELD_BITPOS (type, i))
+	    {
+	      break;
+	    }
+	}
+      if (i < len)
+	{
+	  fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+	}
+      else
+	{
+	  print_longest (stream, 'd', 0, val);
+	}
+      break;
+
+    case TYPE_CODE_FUNC:
+      if (format)
+	{
+	  print_scalar_formatted (valaddr + embedded_offset, type,
+				  format, 0, stream);
+	  break;
+	}
+      /* FIXME, we should consider, at least for ANSI C language, eliminating
+         the distinction made between FUNCs and POINTERs to FUNCs.  */
+      fprintf_filtered (stream, "{");
+      type_print (type, "", stream, -1);
+      fprintf_filtered (stream, "} ");
+      /* Try to print what function it points to, and its address.  */
+      print_address_demangle (address, stream, demangle);
+      break;
+
+    case TYPE_CODE_BOOL:
+      format = format ? format : output_format;
+      if (format)
+	print_scalar_formatted (valaddr + embedded_offset, type,
+				format, 0, stream);
+      else
+	{
+	  val = unpack_long (type, valaddr + embedded_offset);
+	  if (val == 0)
+	    fputs_filtered ("FALSE", stream);
+	  else if (val == 1)
+	    fputs_filtered ("TRUE", stream);
+	  else
+	    fprintf_filtered (stream, "%ld)", (long int) val);
+	}
+      break;
+
+    case TYPE_CODE_RANGE:
+      if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type)))
+	{
+	  m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset,
+			address, stream, format, deref_ref, recurse, pretty);
+	  break;
+	}
+      /* FIXME: create_range_type does not set the unsigned bit in a
+         range type (I think it probably should copy it from the target
+         type), so we won't print values which are too large to
+         fit in a signed integer correctly.  */
+      /* FIXME: Doesn't handle ranges of enums correctly.  (Can't just
+         print with the target type, though, because the size of our type
+         and the target type might differ).  */
+      /* FALLTHROUGH */
+
+    case TYPE_CODE_INT:
+      format = format ? format : output_format;
+      if (format)
+	print_scalar_formatted (valaddr + embedded_offset, type, format,
+				0, stream);
+      else
+	val_print_type_code_int (type, valaddr + embedded_offset, stream);
+      break;
+
+    case TYPE_CODE_CHAR:
+      format = format ? format : output_format;
+      if (format)
+	print_scalar_formatted (valaddr + embedded_offset, type,
+				format, 0, stream);
+      else
+	{
+	  val = unpack_long (type, valaddr + embedded_offset);
+	  if (TYPE_UNSIGNED (type))
+	    fprintf_filtered (stream, "%u", (unsigned int) val);
+	  else
+	    fprintf_filtered (stream, "%d", (int) val);
+	  fputs_filtered (" ", stream);
+	  LA_PRINT_CHAR ((unsigned char) val, stream);
+	}
+      break;
+
+    case TYPE_CODE_FLT:
+      if (format)
+	print_scalar_formatted (valaddr + embedded_offset, type,
+				format, 0, stream);
+      else
+	print_floating (valaddr + embedded_offset, type, stream);
+      break;
+
+    case TYPE_CODE_METHOD:
+      break;
+
+    case TYPE_CODE_BITSTRING:
+    case TYPE_CODE_SET:
+      elttype = TYPE_INDEX_TYPE (type);
+      CHECK_TYPEDEF (elttype);
+      if (TYPE_STUB (elttype))
+	{
+	  fprintf_filtered (stream, _("<incomplete type>"));
+	  gdb_flush (stream);
+	  break;
+	}
+      else
+	{
+	  struct type *range = elttype;
+	  LONGEST low_bound, high_bound;
+	  int i;
+	  int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
+	  int need_comma = 0;
+
+	  if (is_bitstring)
+	    fputs_filtered ("B'", stream);
+	  else
+	    fputs_filtered ("{", stream);
+
+	  i = get_discrete_bounds (range, &low_bound, &high_bound);
+	maybe_bad_bstring:
+	  if (i < 0)
+	    {
+	      fputs_filtered (_("<error value>"), stream);
+	      goto done;
+	    }
+
+	  for (i = low_bound; i <= high_bound; i++)
+	    {
+	      int element = value_bit_index (type, valaddr + embedded_offset,
+					     i);
+	      if (element < 0)
+		{
+		  i = element;
+		  goto maybe_bad_bstring;
+		}
+	      if (is_bitstring)
+		fprintf_filtered (stream, "%d", element);
+	      else if (element)
+		{
+		  if (need_comma)
+		    fputs_filtered (", ", stream);
+		  print_type_scalar (range, i, stream);
+		  need_comma = 1;
+
+		  if (i + 1 <= high_bound
+		      && value_bit_index (type, valaddr + embedded_offset,
+					  ++i))
+		    {
+		      int j = i;
+		      fputs_filtered ("..", stream);
+		      while (i + 1 <= high_bound
+			     && value_bit_index (type,
+						 valaddr + embedded_offset,
+						 ++i))
+			j = i;
+		      print_type_scalar (range, j, stream);
+		    }
+		}
+	    }
+	done:
+	  if (is_bitstring)
+	    fputs_filtered ("'", stream);
+	  else
+	    fputs_filtered ("}", stream);
+	}
+      break;
+
+    case TYPE_CODE_VOID:
+      fprintf_filtered (stream, "void");
+      break;
+
+    case TYPE_CODE_ERROR:
+      fprintf_filtered (stream, _("<error type>"));
+      break;
+
+    case TYPE_CODE_UNDEF:
+      /* This happens (without TYPE_FLAG_STUB set) on systems which don't use
+         dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
+         and no complete type for struct foo in that file.  */
+      fprintf_filtered (stream, _("<incomplete type>"));
+      break;
+
+    default:
+      error (_("Invalid m2 type code %d in symbol table."), TYPE_CODE (type));
+    }
+  gdb_flush (stream);
+  return (0);
 }
diff --git a/gdb/mi/gdb-mi.el b/gdb/mi/gdb-mi.el
index ed1d7b7..7a499d8 100644
--- a/gdb/mi/gdb-mi.el
+++ b/gdb/mi/gdb-mi.el
@@ -170,7 +170,7 @@
   (setq comint-input-sender 'gdbmi-send)
   ;;
   ;; (re-)initialise
-  (setq gdb-frame-address (if gdb-show-main "main" nil)
+  (setq gdb-pc-address (if gdb-show-main "main" nil)
         gdb-previous-frame-address nil
         gdb-memory-address "main"
         gdb-previous-frame nil
@@ -225,7 +225,7 @@
     (setq gdb-output-sink 'user)
     (setq gdb-prompting nil)
     ;; mimic <RET> key to repeat previous command in GDB
-    (if (string-match "^\\S+$" string)
+    (if (not (string-match "^\\s+$" string))
 	(setq gdb-last-command string)
       (if gdb-last-command (setq string gdb-last-command)))
     (if gdb-enable-debug
@@ -563,22 +563,23 @@
     (goto-char (point-min))
     (when (re-search-forward gdb-stack-list-frames-regexp nil t)
       (setq gdb-frame-number (match-string 1))
-      (setq gdb-frame-address (match-string 2))
+      (setq gdb-pc-address (match-string 2))
       (setq gdb-selected-frame (match-string 3))
-      (setq gud-last-frame
-	    (cons (match-string 4) (string-to-number (match-string 5))))
-      (gud-display-frame)
-      (if gud-overlay-arrow-position
-	  (let ((buffer (marker-buffer gud-overlay-arrow-position))
-		(position (marker-position gud-overlay-arrow-position)))
-	    (when buffer
-	      (with-current-buffer buffer
-		(setq fringe-indicator-alist
-		      (if (string-equal gdb-frame-number "0")
-			  nil
-			'((overlay-arrow . hollow-right-triangle))))
-		(setq gud-overlay-arrow-position (make-marker))
-		(set-marker gud-overlay-arrow-position position)))))
+      (when (match-string 4)
+	(setq gud-last-frame
+	      (cons (match-string 4) (string-to-number (match-string 5))))
+	(gud-display-frame)
+	(if gud-overlay-arrow-position
+	    (let ((buffer (marker-buffer gud-overlay-arrow-position))
+		  (position (marker-position gud-overlay-arrow-position)))
+	      (when buffer
+		(with-current-buffer buffer
+		  (setq fringe-indicator-alist
+			(if (string-equal gdb-frame-number "0")
+			    nil
+			  '((overlay-arrow . hollow-right-triangle))))
+		  (setq gud-overlay-arrow-position (make-marker))
+		  (set-marker gud-overlay-arrow-position position))))))
       (if (gdb-get-buffer 'gdb-locals-buffer)
 	  (with-current-buffer (gdb-get-buffer 'gdb-locals-buffer)
 	    (setq mode-name (concat "Locals:" gdb-selected-frame))))
diff --git a/gdb/ppcnbsd-nat.c b/gdb/ppcnbsd-nat.c
index ca19ca0..a200505 100644
--- a/gdb/ppcnbsd-nat.c
+++ b/gdb/ppcnbsd-nat.c
@@ -1,5 +1,7 @@
-/* Native-dependent code for PowerPC's running NetBSD, for GDB.
-   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* Native-dependent code for NetBSD/powerpc.
+
+   Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+
    Contributed by Wasabi Systems, Inc.
 
    This file is part of GDB.
@@ -26,35 +28,37 @@
 #include <machine/pcb.h>
 
 #include "defs.h"
-#include "inferior.h"
-#include "gdb_assert.h"
 #include "gdbcore.h"
+#include "inferior.h"
 #include "regcache.h"
-#include "bsd-kvm.h"
+
+#include "gdb_assert.h"
 
 #include "ppc-tdep.h"
 #include "ppcnbsd-tdep.h"
-
+#include "bsd-kvm.h"
 #include "inf-ptrace.h"
 
 /* Returns true if PT_GETREGS fetches this register.  */
+
 static int
-getregs_supplies (int regno)
+getregs_supplies (int regnum)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 
-  return ((regno >= tdep->ppc_gp0_regnum
-           && regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
-          || regno == tdep->ppc_lr_regnum
-          || regno == tdep->ppc_cr_regnum
-          || regno == tdep->ppc_xer_regnum
-          || regno == tdep->ppc_ctr_regnum
-	  || regno == PC_REGNUM);
+  return ((regnum >= tdep->ppc_gp0_regnum
+           && regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
+          || regnum == tdep->ppc_lr_regnum
+          || regnum == tdep->ppc_cr_regnum
+          || regnum == tdep->ppc_xer_regnum
+          || regnum == tdep->ppc_ctr_regnum
+	  || regnum == PC_REGNUM);
 }
 
 /* Like above, but for PT_GETFPREGS.  */
+
 static int
-getfpregs_supplies (int regno)
+getfpregs_supplies (int regnum)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 
@@ -70,15 +74,15 @@
      combination to the problem.  */
   gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
 
-  return ((regno >= tdep->ppc_fp0_regnum
-           && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
-	  || regno == tdep->ppc_fpscr_regnum);
+  return ((regnum >= tdep->ppc_fp0_regnum
+           && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
+	  || regnum == tdep->ppc_fpscr_regnum);
 }
 
 static void
-ppcnbsd_fetch_inferior_registers (int regno)
+ppcnbsd_fetch_inferior_registers (int regnum)
 {
-  if (regno == -1 || getregs_supplies (regno))
+  if (regnum == -1 || getregs_supplies (regnum))
     {
       struct reg regs;
 
@@ -86,12 +90,11 @@
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
         perror_with_name (_("Couldn't get registers"));
 
-      ppcnbsd_supply_reg ((char *) &regs, regno);
-      if (regno != -1)
-	return;
+      ppc_supply_gregset (&ppcnbsd_gregset, current_regcache,
+			  regnum, &regs, sizeof regs);
     }
 
-  if (regno == -1 || getfpregs_supplies (regno))
+  if (regnum == -1 || getfpregs_supplies (regnum))
     {
       struct fpreg fpregs;
 
@@ -99,16 +102,15 @@
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't get FP registers"));
 
-      ppcnbsd_supply_fpreg ((char *) &fpregs, regno);
-      if (regno != -1)
-	return;
+      ppc_supply_fpregset (&ppcnbsd_fpregset, current_regcache,
+			   regnum, &fpregs, sizeof fpregs);
     }
 }
 
 static void
-ppcnbsd_store_inferior_registers (int regno)
+ppcnbsd_store_inferior_registers (int regnum)
 {
-  if (regno == -1 || getregs_supplies (regno))
+  if (regnum == -1 || getregs_supplies (regnum))
     {
       struct reg regs;
 
@@ -116,17 +118,15 @@
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
 	perror_with_name (_("Couldn't get registers"));
 
-      ppcnbsd_fill_reg ((char *) &regs, regno);
+      ppc_collect_gregset (&ppcnbsd_gregset, current_regcache,
+			   regnum, &regs, sizeof regs);
 
       if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
 	perror_with_name (_("Couldn't write registers"));
-
-      if (regno != -1)
-	return;
     }
 
-  if (regno == -1 || getfpregs_supplies (regno))
+  if (regnum == -1 || getfpregs_supplies (regnum))
     {
       struct fpreg fpregs;
 
@@ -134,8 +134,9 @@
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't get FP registers"));
 
-      ppcnbsd_fill_fpreg ((char *) &fpregs, regno);
-      
+      ppc_collect_fpregset (&ppcnbsd_fpregset, current_regcache,
+			    regnum, &fpregs, sizeof fpregs);
+
       if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't set FP registers"));
@@ -154,19 +155,19 @@
   if (pcb->pcb_sp == 0)
     return 0;
 
-  read_memory (pcb->pcb_sp, (char *) &sf, sizeof sf);
+  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
   regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
   for (i = 0 ; i < 19 ; i++)
     regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 13 + i,
 			 &sf.fixreg[i]);
 
-  read_memory(sf.sp, (char *)&cf, sizeof(cf));
+  read_memory(sf.sp, (gdb_byte *)&cf, sizeof(cf));
   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);
   regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 1, &cf.sp);
 
-  read_memory(cf.sp, (char *)&cf, sizeof(cf));
+  read_memory(cf.sp, (gdb_byte *)&cf, sizeof(cf));
   regcache_raw_supply (regcache, tdep->ppc_lr_regnum, &cf.lr);
   regcache_raw_supply (regcache, PC_REGNUM, &cf.lr);
 
@@ -180,8 +181,10 @@
 _initialize_ppcnbsd_nat (void)
 {
   struct target_ops *t;
+
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (ppcnbsd_supply_pcb);
+
   /* Add in local overrides.  */
   t = inf_ptrace_target ();
   t->to_fetch_registers = ppcnbsd_fetch_inferior_registers;
diff --git a/gdb/ppcnbsd-tdep.c b/gdb/ppcnbsd-tdep.c
index 57ba742..6bbdf4f 100644
--- a/gdb/ppcnbsd-tdep.c
+++ b/gdb/ppcnbsd-tdep.c
@@ -1,6 +1,6 @@
-/* Target-dependent code for PowerPC systems running NetBSD.
+/* Target-dependent code for NetBSD/powerpc.
 
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    Contributed by Wasabi Systems, Inc.
 
@@ -22,225 +22,58 @@
    Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
-#include "gdbcore.h"
-#include "regcache.h"
-#include "target.h"
-#include "breakpoint.h"
-#include "value.h"
+#include "gdbtypes.h"
 #include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
 
 #include "ppc-tdep.h"
 #include "ppcnbsd-tdep.h"
-#include "nbsd-tdep.h"
-#include "tramp-frame.h"
-#include "trad-frame.h"
-#include "gdb_assert.h"
 #include "solib-svr4.h"
 
-#define REG_FIXREG_OFFSET(x)	((x) * 4)
-#define REG_LR_OFFSET		(32 * 4)
-#define REG_CR_OFFSET		(33 * 4)
-#define REG_XER_OFFSET		(34 * 4)
-#define REG_CTR_OFFSET		(35 * 4)
-#define REG_PC_OFFSET		(36 * 4)
-#define SIZEOF_STRUCT_REG	(37 * 4)
+/* Register offsets from <machine/reg.h>.  */
+struct ppc_reg_offsets ppcnbsd_reg_offsets;
+
 
-#define FPREG_FPR_OFFSET(x)	((x) * 8)
-#define FPREG_FPSCR_OFFSET	(32 * 8)
-#define SIZEOF_STRUCT_FPREG	(33 * 8)
+/* Core file support.  */
 
-void
-ppcnbsd_supply_reg (char *regs, int regno)
+/* NetBSD/powerpc register set.  */
+
+struct regset ppcnbsd_gregset =
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  int i;
-
-  for (i = 0; i < ppc_num_gprs; i++)
-    {
-      if (regno == tdep->ppc_gp0_regnum + i || regno == -1)
-	regcache_raw_supply (current_regcache, tdep->ppc_gp0_regnum + i,
-			     regs + REG_FIXREG_OFFSET (i));
-    }
-
-  if (regno == tdep->ppc_lr_regnum || regno == -1)
-    regcache_raw_supply (current_regcache, tdep->ppc_lr_regnum,
-			 regs + REG_LR_OFFSET);
-
-  if (regno == tdep->ppc_cr_regnum || regno == -1)
-    regcache_raw_supply (current_regcache, tdep->ppc_cr_regnum,
-			 regs + REG_CR_OFFSET);
-
-  if (regno == tdep->ppc_xer_regnum || regno == -1)
-    regcache_raw_supply (current_regcache, tdep->ppc_xer_regnum,
-			 regs + REG_XER_OFFSET);
-
-  if (regno == tdep->ppc_ctr_regnum || regno == -1)
-    regcache_raw_supply (current_regcache, tdep->ppc_ctr_regnum,
-			 regs + REG_CTR_OFFSET);
-
-  if (regno == PC_REGNUM || regno == -1)
-    regcache_raw_supply (current_regcache, PC_REGNUM,
-			 regs + REG_PC_OFFSET);
-}
-
-void
-ppcnbsd_fill_reg (char *regs, int regno)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  int i;
-
-  for (i = 0; i < ppc_num_gprs; i++)
-    {
-      if (regno == tdep->ppc_gp0_regnum + i || regno == -1)
-	regcache_raw_collect (current_regcache, tdep->ppc_gp0_regnum + i,
-			      regs + REG_FIXREG_OFFSET (i));
-    }
-
-  if (regno == tdep->ppc_lr_regnum || regno == -1)
-    regcache_raw_collect (current_regcache, tdep->ppc_lr_regnum,
-			  regs + REG_LR_OFFSET);
-
-  if (regno == tdep->ppc_cr_regnum || regno == -1)
-    regcache_raw_collect (current_regcache, tdep->ppc_cr_regnum,
-			  regs + REG_CR_OFFSET);
-
-  if (regno == tdep->ppc_xer_regnum || regno == -1)
-    regcache_raw_collect (current_regcache, tdep->ppc_xer_regnum,
-			  regs + REG_XER_OFFSET);
-
-  if (regno == tdep->ppc_ctr_regnum || regno == -1)
-    regcache_raw_collect (current_regcache, tdep->ppc_ctr_regnum,
-			  regs + REG_CTR_OFFSET);
-
-  if (regno == PC_REGNUM || regno == -1)
-    regcache_raw_collect (current_regcache, PC_REGNUM, regs + REG_PC_OFFSET);
-}
-
-void
-ppcnbsd_supply_fpreg (char *fpregs, int regno)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  int i;
-
-  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
-     point registers.  Traditionally, GDB's register set has still
-     listed the floating point registers for such machines, so this
-     code is harmless.  However, the new E500 port actually omits the
-     floating point registers entirely from the register set --- they
-     don't even have register numbers assigned to them.
-
-     It's not clear to me how best to update this code, so this assert
-     will alert the first person to encounter the NetBSD/E500
-     combination to the problem.  */
-  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
-
-  for (i = 0; i < ppc_num_fprs; i++)
-    {
-      if (regno == tdep->ppc_fp0_regnum + i || regno == -1)
-	regcache_raw_supply (current_regcache, tdep->ppc_fp0_regnum + i,
-			     fpregs + FPREG_FPR_OFFSET (i));
-    }
-
-  if (regno == tdep->ppc_fpscr_regnum || regno == -1)
-    regcache_raw_supply (current_regcache, tdep->ppc_fpscr_regnum,
-			 fpregs + FPREG_FPSCR_OFFSET);
-}
-
-void
-ppcnbsd_fill_fpreg (char *fpregs, int regno)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  int i;
-
-  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
-     point registers.  Traditionally, GDB's register set has still
-     listed the floating point registers for such machines, so this
-     code is harmless.  However, the new E500 port actually omits the
-     floating point registers entirely from the register set --- they
-     don't even have register numbers assigned to them.
-
-     It's not clear to me how best to update this code, so this assert
-     will alert the first person to encounter the NetBSD/E500
-     combination to the problem.  */
-  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
-
-  for (i = 0; i < ppc_num_fprs; i++)
-    {
-      if (regno == tdep->ppc_fp0_regnum + i || regno == -1)
-	regcache_raw_collect (current_regcache, tdep->ppc_fp0_regnum + i,
-			      fpregs + FPREG_FPR_OFFSET (i));
-    }
-
-  if (regno == tdep->ppc_fpscr_regnum || regno == -1)
-    regcache_raw_collect (current_regcache, tdep->ppc_fpscr_regnum,
-			  fpregs + FPREG_FPSCR_OFFSET);
-}
-
-static void
-fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
-                      CORE_ADDR ignore)
-{
-  char *regs, *fpregs;
-
-  /* We get everything from one section.  */
-  if (which != 0)
-    return;
-
-  regs = core_reg_sect;
-  fpregs = core_reg_sect + SIZEOF_STRUCT_REG;
-
-  /* Integer registers.  */
-  ppcnbsd_supply_reg (regs, -1);
-
-  /* Floating point registers.  */
-  ppcnbsd_supply_fpreg (fpregs, -1);
-}
-
-static void
-fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
-                         CORE_ADDR ignore)
-{
-  switch (which)
-    {
-    case 0:  /* Integer registers.  */
-      if (core_reg_size != SIZEOF_STRUCT_REG)
-	warning (_("Wrong size register set in core file."));
-      else
-	ppcnbsd_supply_reg (core_reg_sect, -1);
-      break;
-
-    case 2:  /* Floating point registers.  */
-      if (core_reg_size != SIZEOF_STRUCT_FPREG)
-	warning (_("Wrong size FP register set in core file."));
-      else
-	ppcnbsd_supply_fpreg (core_reg_sect, -1);
-      break;
-
-    default:
-      /* Don't know what kind of register request this is; just ignore it.  */
-      break;
-    }
-}
-
-static struct core_fns ppcnbsd_core_fns =
-{
-  bfd_target_unknown_flavour,		/* core_flavour */
-  default_check_format,			/* check_format */
-  default_core_sniffer,			/* core_sniffer */
-  fetch_core_registers,			/* core_read_registers */
-  NULL					/* next */
+  &ppcnbsd_reg_offsets,
+  ppc_supply_gregset
 };
 
-static struct core_fns ppcnbsd_elfcore_fns =
+struct regset ppcnbsd_fpregset =
 {
-  bfd_target_elf_flavour,		/* core_flavour */
-  default_check_format,			/* check_format */
-  default_core_sniffer,			/* core_sniffer */
-  fetch_elfcore_registers,		/* core_read_registers */
-  NULL					/* next */
+  &ppcnbsd_reg_offsets,
+  ppc_supply_fpregset
 };
 
-/* NetBSD is confused.  It appears that 1.5 was using the correct SVr4
+/* Return the appropriate register set for the core section identified
+   by SECT_NAME and SECT_SIZE.  */
+
+static const struct regset *
+ppcnbsd_regset_from_core_section (struct gdbarch *gdbarch,
+				  const char *sect_name, size_t sect_size)
+{
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= 148)
+    return &ppcnbsd_gregset;
+
+  if (strcmp (sect_name, ".reg2") == 0 && sect_size >= 264)
+    return &ppcnbsd_fpregset;
+
+  return NULL;
+}
+
+
+/* NetBSD is confused.  It appears that 1.5 was using the correct SVR4
    convention but, 1.6 switched to the below broken convention.  For
    the moment use the broken convention.  Ulgh!.  */
 
@@ -249,6 +82,7 @@
 		      struct regcache *regcache, gdb_byte *readbuf,
 		      const gdb_byte *writebuf)
 {
+#if 0
   if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
        || TYPE_CODE (valtype) == TYPE_CODE_UNION)
       && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
@@ -259,9 +93,15 @@
 	   || TYPE_LENGTH (valtype) == 8))
     return RETURN_VALUE_STRUCT_CONVENTION;
   else
+#endif
     return ppc_sysv_abi_broken_return_value (gdbarch, valtype, regcache,
 					     readbuf, writebuf);
 }
+
+
+/* Signal trampolines.  */
+
+static const struct tramp_frame ppcnbsd2_sigtramp;
 
 static void
 ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
@@ -269,54 +109,73 @@
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
-  CORE_ADDR base;
-  CORE_ADDR offset;
-  int i;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  CORE_ADDR addr, base;
+  int i;
 
   base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
-  offset = base + 0x18 + 2 * tdep->wordsize;
-  for (i = 0; i < ppc_num_gprs; i++)
+  if (self == &ppcnbsd2_sigtramp)
+    addr = base + 0x10 + 2 * tdep->wordsize;
+  else
+    addr = base + 0x18 + 2 * tdep->wordsize;
+  for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
     {
       int regnum = i + tdep->ppc_gp0_regnum;
-      trad_frame_set_reg_addr (this_cache, regnum, offset);
-      offset += tdep->wordsize;
+      trad_frame_set_reg_addr (this_cache, regnum, addr);
     }
-  trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, offset);
-  offset += tdep->wordsize;
-  trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, offset);
-  offset += tdep->wordsize;
-  trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, offset);
-  offset += tdep->wordsize;
-  trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, offset);
-  offset += tdep->wordsize;
-  trad_frame_set_reg_addr (this_cache, PC_REGNUM, offset); /* SRR0? */
-  offset += tdep->wordsize;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
+  addr += tdep->wordsize;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
+  addr += tdep->wordsize;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
+  addr += tdep->wordsize;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
+  addr += tdep->wordsize;
+  trad_frame_set_reg_addr (this_cache, PC_REGNUM, addr); /* SRR0? */
+  addr += tdep->wordsize;
 
   /* Construct the frame ID using the function start.  */
   trad_frame_set_id (this_cache, frame_id_build (base, func));
 }
 
-/* Given the NEXT frame, examine the instructions at and around this
-   frame's resume address (aka PC) to see of they look like a signal
-   trampoline.  Return the address of the trampolines first
-   instruction, or zero if it isn't a signal trampoline.  */
-
-static const struct tramp_frame ppcnbsd_sigtramp = {
+static const struct tramp_frame ppcnbsd_sigtramp =
+{
   SIGTRAMP_FRAME,
-  4, /* insn size */
-  { /* insn */
-    { 0x38610018, -1 }, /* addi r3,r1,24 */
-    { 0x38000127, -1 }, /* li r0,295 */
-    { 0x44000002, -1 }, /* sc */
-    { 0x38000001, -1 }, /* li r0,1 */
-    { 0x44000002, -1 }, /* sc */
+  4,
+  {
+    { 0x3821fff0, -1 },		/* add r1,r1,-16 */
+    { 0x4e800021, -1 },		/* blrl */
+    { 0x38610018, -1 },		/* addi r3,r1,24 */
+    { 0x38000127, -1 },		/* li r0,295 */
+    { 0x44000002, -1 },		/* sc */
+    { 0x38000001, -1 },		/* li r0,1 */
+    { 0x44000002, -1 },		/* sc */
     { TRAMP_SENTINEL_INSN, -1 }
   },
   ppcnbsd_sigtramp_cache_init
 };
 
+/* NetBSD 2.0 introduced a slightly different signal trampoline.  */
+
+static const struct tramp_frame ppcnbsd2_sigtramp =
+{
+  SIGTRAMP_FRAME,
+  4,
+  {
+    { 0x3821fff0, -1 },		/* add r1,r1,-16 */
+    { 0x4e800021, -1 },		/* blrl */
+    { 0x38610010, -1 },		/* addi r3,r1,16 */
+    { 0x38000127, -1 },		/* li r0,295 */
+    { 0x44000002, -1 },		/* sc */
+    { 0x38000001, -1 },		/* li r0,1 */
+    { 0x44000002, -1 },		/* sc */
+    { TRAMP_SENTINEL_INSN, -1 }
+  },
+  ppcnbsd_sigtramp_cache_init
+};
+
+
 static void
 ppcnbsd_init_abi (struct gdbarch_info info,
                   struct gdbarch *gdbarch)
@@ -324,10 +183,21 @@
   /* For NetBSD, this is an on again, off again thing.  Some systems
      do use the broken struct convention, and some don't.  */
   set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
-  set_solib_svr4_fetch_link_map_offsets (gdbarch,
-                                nbsd_ilp32_solib_svr4_fetch_link_map_offsets);
+
+  /* NetBSD uses SVR4-style shared libraries.  */
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  set_gdbarch_regset_from_core_section
+    (gdbarch, ppcnbsd_regset_from_core_section);
+
   tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
+  tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
 }
+
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_ppcnbsd_tdep (void);
 
 void
 _initialize_ppcnbsd_tdep (void)
@@ -335,6 +205,27 @@
   gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF,
 			  ppcnbsd_init_abi);
 
-  deprecated_add_core_fns (&ppcnbsd_core_fns);
-  deprecated_add_core_fns (&ppcnbsd_elfcore_fns);
+  /* Avoid initializing the register offsets again if they were
+     already initailized by ppcnbsd-nat.c.  */
+  if (ppcnbsd_reg_offsets.pc_offset == 0)
+    {
+      /* General-purpose registers.  */
+      ppcnbsd_reg_offsets.r0_offset = 0;
+      ppcnbsd_reg_offsets.lr_offset = 128;
+      ppcnbsd_reg_offsets.cr_offset = 132;
+      ppcnbsd_reg_offsets.xer_offset = 136;
+      ppcnbsd_reg_offsets.ctr_offset = 140;
+      ppcnbsd_reg_offsets.pc_offset = 144;
+      ppcnbsd_reg_offsets.ps_offset = -1;
+      ppcnbsd_reg_offsets.mq_offset = -1;
+
+      /* Floating-point registers.  */
+      ppcnbsd_reg_offsets.f0_offset = 0;
+      ppcnbsd_reg_offsets.fpscr_offset = 256;
+
+      /* AltiVec registers.  */
+      ppcnbsd_reg_offsets.vr0_offset = 0;
+      ppcnbsd_reg_offsets.vrsave_offset = 512;
+      ppcnbsd_reg_offsets.vscr_offset = 524;
+    }
 }
diff --git a/gdb/ppcnbsd-tdep.h b/gdb/ppcnbsd-tdep.h
index 968cf57..eee5449 100644
--- a/gdb/ppcnbsd-tdep.h
+++ b/gdb/ppcnbsd-tdep.h
@@ -1,5 +1,6 @@
-/* Common target dependent code for GDB on PowerPC systems running NetBSD.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+/* Target-dependent code for NetBSD/powerpc.
+
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,10 +22,15 @@
 #ifndef PPCNBSD_TDEP_H
 #define PPCNBSD_TDEP_H
 
-void ppcnbsd_supply_reg (char *, int);
-void ppcnbsd_fill_reg (char *, int);
+#include <stddef.h>
 
-void ppcnbsd_supply_fpreg (char *, int);
-void ppcnbsd_fill_fpreg (char *, int);
+struct regset;
 
-#endif /* PPCNBSD_TDEP_H */
+/* Register offsets for NetBSD/powerpc.  */
+extern struct ppc_reg_offsets ppcnbsd_reg_offsets;
+
+/* Register sets for NetBSD/powerpc.  */
+extern struct regset ppcnbsd_gregset;
+extern struct regset ppcnbsd_fpregset;
+
+#endif /* ppcnbsd-tdep.h */
diff --git a/gdb/version.in b/gdb/version.in
index 144b14d..0fbdab0 100644
--- a/gdb/version.in
+++ b/gdb/version.in
@@ -1 +1 @@
-6.4.50.20060512-cvs
+6.4.50.20060514-cvs
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 76baa3c..ef48f86 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-12  Anton Blanchard  <anton@samba.org>
+
+	* cplus-dem.c (demangle_fund_type): Ensure buf is large enough to
+	hold "int%u_t".
+
 2006-04-24  Julian Brown  <julian@codesourcery.com>
 
 	* floatformat.c (floatformat_to_double): Fix (biased) exponent=0 case.
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 8b60434a..1f8b1fc 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -3693,7 +3693,7 @@
 {
   int done = 0;
   int success = 1;
-  char buf[10];
+  char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
   unsigned int dec = 0;
   type_kind_t tk = tk_integral;
 
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index b3c5b6f..37d1931 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,9 @@
+2006-05-14  Thiemo Seufer  <ths@mips.com>
+
+	* mips16-opc.c (I1, I32, I64): New shortcut defines.
+	(mips16_opcodes): Change membership of instructions to their
+	lowest baseline ISA.
+
 2006-05-09  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* i386-dis.c (grps): Update sgdt/sidt for 64bit.
diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c
index 24b6107..8144986 100644
--- a/opcodes/mips16-opc.c
+++ b/opcodes/mips16-opc.c
@@ -58,59 +58,61 @@
 
 #define TRAP	INSN_TRAP
 
+#define I1	INSN_ISA1
 #define I3	INSN_ISA3
-
-#define T3      INSN_3900
+#define I32	INSN_ISA32
+#define I64	INSN_ISA64
+#define T3	INSN_3900
 
 const struct mips_opcode mips16_opcodes[] =
 {
 /* name,    args,	match,	mask,	pinfo,         	pinfo2, membership */
-{"nop",	    "",		0x6500, 0xffff, RD_Z,		0,	0 }, /* move $0,$Z */
-{"la",	    "x,A",	0x0800, 0xf800, WR_x|RD_PC,	0,	0 },
-{"abs",	    "x,w",	0, (int) M_ABS, INSN_MACRO,	0,	0 },
-{"addiu",   "y,x,4",	0x4000, 0xf810, WR_y|RD_x,	0,	0 },
-{"addiu",   "x,k",	0x4800, 0xf800, WR_x|RD_x,	0,	0 },
-{"addiu",   "S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	0 },
-{"addiu",   "S,S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	0 },
-{"addiu",   "x,P,V",	0x0800, 0xf800, WR_x|RD_PC,	0,	0 },
-{"addiu",   "x,S,V",	0x0000, 0xf800, WR_x|RD_SP,	0,	0 },
-{"addu",    "z,v,y",	0xe001, 0xf803, WR_z|RD_x|RD_y,	0,	0 },
-{"addu",    "y,x,4",	0x4000, 0xf810, WR_y|RD_x,	0,	0 },
-{"addu",    "x,k",	0x4800, 0xf800, WR_x|RD_x,	0,	0 },
-{"addu",    "S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	0 },
-{"addu",    "S,S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	0 },
-{"addu",    "x,P,V",	0x0800, 0xf800, WR_x|RD_PC,	0,	0 },
-{"addu",    "x,S,V",	0x0000, 0xf800, WR_x|RD_SP,	0,	0 },
-{"and",	    "x,y",	0xe80c, 0xf81f, WR_x|RD_x|RD_y,	0,	0 },
-{"b",	    "q",	0x1000, 0xf800, BR,		0,	0 },
-{"beq",	    "x,y,p",	0, (int) M_BEQ, INSN_MACRO,	0,	0 },
-{"beq",     "x,U,p",	0, (int) M_BEQ_I, INSN_MACRO,	0,	0 },
-{"beqz",    "x,p",	0x2000, 0xf800, BR|RD_x,	0,	0 },
-{"bge",	    "x,y,p",	0, (int) M_BGE, INSN_MACRO,	0,	0 },
-{"bge",     "x,8,p",	0, (int) M_BGE_I, INSN_MACRO,	0,	0 },
-{"bgeu",    "x,y,p",	0, (int) M_BGEU, INSN_MACRO,	0,	0 },
-{"bgeu",    "x,8,p",	0, (int) M_BGEU_I, INSN_MACRO,	0,	0 },
-{"bgt",	    "x,y,p",	0, (int) M_BGT, INSN_MACRO,	0,	0 },
-{"bgt",     "x,8,p",	0, (int) M_BGT_I, INSN_MACRO,	0,	0 },
-{"bgtu",    "x,y,p",	0, (int) M_BGTU, INSN_MACRO,	0,	0 },
-{"bgtu",    "x,8,p",	0, (int) M_BGTU_I, INSN_MACRO,	0,	0 },
-{"ble",	    "x,y,p",	0, (int) M_BLE, INSN_MACRO,	0,	0 },
-{"ble",     "x,8,p",	0, (int) M_BLE_I, INSN_MACRO,	0,	0 },
-{"bleu",    "x,y,p",	0, (int) M_BLEU, INSN_MACRO,	0,	0 },
-{"bleu",    "x,8,p",	0, (int) M_BLEU_I, INSN_MACRO,	0,	0 },
-{"blt",	    "x,y,p",	0, (int) M_BLT, INSN_MACRO,	0,	0 },
-{"blt",     "x,8,p",	0, (int) M_BLT_I, INSN_MACRO,	0,	0 },
-{"bltu",    "x,y,p",	0, (int) M_BLTU, INSN_MACRO,	0,	0 },
-{"bltu",    "x,8,p",	0, (int) M_BLTU_I, INSN_MACRO,	0,	0 },
-{"bne",	    "x,y,p",	0, (int) M_BNE, INSN_MACRO,	0,	0 },
-{"bne",     "x,U,p",	0, (int) M_BNE_I, INSN_MACRO,	0,	0 },
-{"bnez",    "x,p",	0x2800, 0xf800, BR|RD_x,	0,	0 },
-{"break",   "6",	0xe805, 0xf81f, TRAP,		0,	0 },
-{"bteqz",   "p",	0x6000, 0xff00, BR|RD_T,	0,	0 },
-{"btnez",   "p",	0x6100, 0xff00, BR|RD_T,	0,	0 },
-{"cmpi",    "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	0 },
-{"cmp",	    "x,y",	0xe80a, 0xf81f, WR_T|RD_x|RD_y,	0,	0 },
-{"cmp",     "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	0 },
+{"nop",	    "",		0x6500, 0xffff, RD_Z,		0,	I1 }, /* move $0,$Z */
+{"la",	    "x,A",	0x0800, 0xf800, WR_x|RD_PC,	0,	I1 },
+{"abs",	    "x,w",	0, (int) M_ABS, INSN_MACRO,	0,	I1 },
+{"addiu",   "y,x,4",	0x4000, 0xf810, WR_y|RD_x,	0,	I1 },
+{"addiu",   "x,k",	0x4800, 0xf800, WR_x|RD_x,	0,	I1 },
+{"addiu",   "S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
+{"addiu",   "S,S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
+{"addiu",   "x,P,V",	0x0800, 0xf800, WR_x|RD_PC,	0,	I1 },
+{"addiu",   "x,S,V",	0x0000, 0xf800, WR_x|RD_SP,	0,	I1 },
+{"addu",    "z,v,y",	0xe001, 0xf803, WR_z|RD_x|RD_y,	0,	I1 },
+{"addu",    "y,x,4",	0x4000, 0xf810, WR_y|RD_x,	0,	I1 },
+{"addu",    "x,k",	0x4800, 0xf800, WR_x|RD_x,	0,	I1 },
+{"addu",    "S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
+{"addu",    "S,S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
+{"addu",    "x,P,V",	0x0800, 0xf800, WR_x|RD_PC,	0,	I1 },
+{"addu",    "x,S,V",	0x0000, 0xf800, WR_x|RD_SP,	0,	I1 },
+{"and",	    "x,y",	0xe80c, 0xf81f, WR_x|RD_x|RD_y,	0,	I1 },
+{"b",	    "q",	0x1000, 0xf800, BR,		0,	I1 },
+{"beq",	    "x,y,p",	0, (int) M_BEQ, INSN_MACRO,	0,	I1 },
+{"beq",     "x,U,p",	0, (int) M_BEQ_I, INSN_MACRO,	0,	I1 },
+{"beqz",    "x,p",	0x2000, 0xf800, BR|RD_x,	0,	I1 },
+{"bge",	    "x,y,p",	0, (int) M_BGE, INSN_MACRO,	0,	I1 },
+{"bge",     "x,8,p",	0, (int) M_BGE_I, INSN_MACRO,	0,	I1 },
+{"bgeu",    "x,y,p",	0, (int) M_BGEU, INSN_MACRO,	0,	I1 },
+{"bgeu",    "x,8,p",	0, (int) M_BGEU_I, INSN_MACRO,	0,	I1 },
+{"bgt",	    "x,y,p",	0, (int) M_BGT, INSN_MACRO,	0,	I1 },
+{"bgt",     "x,8,p",	0, (int) M_BGT_I, INSN_MACRO,	0,	I1 },
+{"bgtu",    "x,y,p",	0, (int) M_BGTU, INSN_MACRO,	0,	I1 },
+{"bgtu",    "x,8,p",	0, (int) M_BGTU_I, INSN_MACRO,	0,	I1 },
+{"ble",	    "x,y,p",	0, (int) M_BLE, INSN_MACRO,	0,	I1 },
+{"ble",     "x,8,p",	0, (int) M_BLE_I, INSN_MACRO,	0,	I1 },
+{"bleu",    "x,y,p",	0, (int) M_BLEU, INSN_MACRO,	0,	I1 },
+{"bleu",    "x,8,p",	0, (int) M_BLEU_I, INSN_MACRO,	0,	I1 },
+{"blt",	    "x,y,p",	0, (int) M_BLT, INSN_MACRO,	0,	I1 },
+{"blt",     "x,8,p",	0, (int) M_BLT_I, INSN_MACRO,	0,	I1 },
+{"bltu",    "x,y,p",	0, (int) M_BLTU, INSN_MACRO,	0,	I1 },
+{"bltu",    "x,8,p",	0, (int) M_BLTU_I, INSN_MACRO,	0,	I1 },
+{"bne",	    "x,y,p",	0, (int) M_BNE, INSN_MACRO,	0,	I1 },
+{"bne",     "x,U,p",	0, (int) M_BNE_I, INSN_MACRO,	0,	I1 },
+{"bnez",    "x,p",	0x2800, 0xf800, BR|RD_x,	0,	I1 },
+{"break",   "6",	0xe805, 0xf81f, TRAP,		0,	I1 },
+{"bteqz",   "p",	0x6000, 0xff00, BR|RD_T,	0,	I1 },
+{"btnez",   "p",	0x6100, 0xff00, BR|RD_T,	0,	I1 },
+{"cmpi",    "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	I1 },
+{"cmp",	    "x,y",	0xe80a, 0xf81f, WR_T|RD_x|RD_y,	0,	I1 },
+{"cmp",     "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	I1 },
 {"dla",	    "y,E",	0xfe00, 0xff00, WR_y|RD_PC, 	0,	I3 },
 {"daddiu",  "y,x,4",	0x4010, 0xf810, WR_y|RD_x, 	0,	I3 },
 {"daddiu",  "y,j",	0xfd00, 0xff00, WR_y|RD_y, 	0,	I3 },
@@ -126,20 +128,20 @@
 {"daddu",   "y,P,W",	0xfe00, 0xff00, WR_y|RD_PC, 	0,	I3 },
 {"daddu",   "y,S,W",	0xff00, 0xff00, WR_y|RD_SP, 	0,	I3 },
 {"ddiv",    "0,x,y",	0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 	0,	I3 },
-{"ddiv",    "z,v,y",	0, (int) M_DDIV_3, INSN_MACRO,	0,	0 },
+{"ddiv",    "z,v,y",	0, (int) M_DDIV_3, INSN_MACRO,	0,	I1 },
 {"ddivu",   "0,x,y",	0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
-{"ddivu",   "z,v,y",	0, (int) M_DDIVU_3, INSN_MACRO,	0,	0 },
-{"div",     "0,x,y",	0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	0 },
-{"div",     "z,v,y",	0, (int) M_DIV_3, INSN_MACRO,	0,	0 },
-{"divu",    "0,x,y",	0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	0 },
-{"divu",    "z,v,y",	0, (int) M_DIVU_3, INSN_MACRO,	0,	0 },
+{"ddivu",   "z,v,y",	0, (int) M_DDIVU_3, INSN_MACRO,	0,	I1 },
+{"div",     "0,x,y",	0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
+{"div",     "z,v,y",	0, (int) M_DIV_3, INSN_MACRO,	0,	I1 },
+{"divu",    "0,x,y",	0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
+{"divu",    "z,v,y",	0, (int) M_DIVU_3, INSN_MACRO,	0,	I1 },
 {"dmul",    "z,v,y",	0, (int) M_DMUL, INSN_MACRO, 	0,	I3 },
 {"dmult",   "x,y",	0xe81c, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
 {"dmultu",  "x,y",	0xe81d, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
 {"drem",    "0,x,y",	0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
-{"drem",    "z,v,y",	0, (int) M_DREM_3, INSN_MACRO,	0,	0 },
+{"drem",    "z,v,y",	0, (int) M_DREM_3, INSN_MACRO,	0,	I1 },
 {"dremu",   "0,x,y",	0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
-{"dremu",   "z,v,y",	0, (int) M_DREMU_3, INSN_MACRO,	0,	0 },
+{"dremu",   "z,v,y",	0, (int) M_DREMU_3, INSN_MACRO,	0,	I1 },
 {"dsllv",   "y,x",	0xe814, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
 {"dsll",    "x,w,[",	0x3001, 0xf803, WR_x|RD_y, 	0,	I3 },
 {"dsll",    "y,x",	0xe814, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
@@ -150,92 +152,92 @@
 {"dsrl",    "y,]",	0xe808, 0xf81f, WR_y|RD_y, 	0,	I3 },
 {"dsrl",    "y,x",	0xe816, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
 {"dsubu",   "z,v,y",	0xe002, 0xf803, WR_z|RD_x|RD_y, 0,	I3 },
-{"dsubu",   "y,x,4",	0, (int) M_DSUBU_I, INSN_MACRO,	0,	0 },
-{"dsubu",   "y,j",	0, (int) M_DSUBU_I_2, INSN_MACRO, 0,	0 },
-{"exit",    "L",	0xed09, 0xff1f, TRAP,		0,	0 },
-{"exit",    "L",	0xee09, 0xff1f, TRAP,		0,	0 },
-{"exit",    "L",	0xef09, 0xff1f, TRAP,		0,	0 },
-{"entry",   "l",	0xe809, 0xf81f, TRAP,		0,	0 },
-{"extend",  "e",	0xf000, 0xf800, 0,		0,	0 },
-{"jalr",    "x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	0 },
-{"jalr",    "R,x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	0 },
-{"jal",     "x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	0 },
-{"jal",     "R,x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	0 },
-{"jal",	    "a",	0x1800, 0xfc00, UBD|WR_31,	0,	0 },
-{"jalx",    "a",	0x1c00, 0xfc00, UBD|WR_31,	0,	0 },
-{"jr",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	0 },
-{"jr",	    "R",	0xe820, 0xffff, UBD|RD_31,	0,	0 },
-{"j",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	0 },
-{"j",	    "R",	0xe820, 0xffff, UBD|RD_31,	0,	0 },
-{"lb",	    "y,5(x)",	0x8000, 0xf800, WR_y|RD_x,	0,	0 },
-{"lbu",	    "y,5(x)",	0xa000, 0xf800, WR_y|RD_x,	0,	0 },
+{"dsubu",   "y,x,4",	0, (int) M_DSUBU_I, INSN_MACRO,	0,	I1 },
+{"dsubu",   "y,j",	0, (int) M_DSUBU_I_2, INSN_MACRO, 0,	I1 },
+{"exit",    "L",	0xed09, 0xff1f, TRAP,		0,	I1 },
+{"exit",    "L",	0xee09, 0xff1f, TRAP,		0,	I1 },
+{"exit",    "L",	0xef09, 0xff1f, TRAP,		0,	I1 },
+{"entry",   "l",	0xe809, 0xf81f, TRAP,		0,	I1 },
+{"extend",  "e",	0xf000, 0xf800, 0,		0,	I1 },
+{"jalr",    "x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
+{"jalr",    "R,x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
+{"jal",     "x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
+{"jal",     "R,x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
+{"jal",	    "a",	0x1800, 0xfc00, UBD|WR_31,	0,	I1 },
+{"jalx",    "a",	0x1c00, 0xfc00, UBD|WR_31,	0,	I1 },
+{"jr",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	I1 },
+{"jr",	    "R",	0xe820, 0xffff, UBD|RD_31,	0,	I1 },
+{"j",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	I1 },
+{"j",	    "R",	0xe820, 0xffff, UBD|RD_31,	0,	I1 },
+{"lb",	    "y,5(x)",	0x8000, 0xf800, WR_y|RD_x,	0,	I1 },
+{"lbu",	    "y,5(x)",	0xa000, 0xf800, WR_y|RD_x,	0,	I1 },
 {"ld",	    "y,D(x)",	0x3800, 0xf800, WR_y|RD_x, 	0,	I3 },
 {"ld",	    "y,B",	0xfc00, 0xff00, WR_y|RD_PC, 	0,	I3 },
 {"ld",	    "y,D(P)",	0xfc00, 0xff00, WR_y|RD_PC, 	0,	I3 },
 {"ld",	    "y,D(S)",	0xf800, 0xff00, WR_y|RD_SP, 	0,	I3 },
-{"lh",	    "y,H(x)",	0x8800, 0xf800, WR_y|RD_x,	0,	0 },
-{"lhu",	    "y,H(x)",	0xa800, 0xf800, WR_y|RD_x,	0,	0 },
-{"li",	    "x,U",	0x6800, 0xf800, WR_x,		0,	0 },
-{"lw",	    "y,W(x)",	0x9800, 0xf800, WR_y|RD_x,	0,	0 },
-{"lw",	    "x,A",	0xb000, 0xf800, WR_x|RD_PC,	0,	0 },
-{"lw",	    "x,V(P)",	0xb000, 0xf800, WR_x|RD_PC,	0,	0 },
-{"lw",	    "x,V(S)",	0x9000, 0xf800, WR_x|RD_SP,	0,	0 },
+{"lh",	    "y,H(x)",	0x8800, 0xf800, WR_y|RD_x,	0,	I1 },
+{"lhu",	    "y,H(x)",	0xa800, 0xf800, WR_y|RD_x,	0,	I1 },
+{"li",	    "x,U",	0x6800, 0xf800, WR_x,		0,	I1 },
+{"lw",	    "y,W(x)",	0x9800, 0xf800, WR_y|RD_x,	0,	I1 },
+{"lw",	    "x,A",	0xb000, 0xf800, WR_x|RD_PC,	0,	I1 },
+{"lw",	    "x,V(P)",	0xb000, 0xf800, WR_x|RD_PC,	0,	I1 },
+{"lw",	    "x,V(S)",	0x9000, 0xf800, WR_x|RD_SP,	0,	I1 },
 {"lwu",     "y,W(x)",	0xb800, 0xf800, WR_y|RD_x, 	0,	I3 },
-{"mfhi",    "x",	0xe810, 0xf8ff, WR_x|RD_HI,	0,	0 },
-{"mflo",    "x",	0xe812, 0xf8ff, WR_x|RD_LO,	0,	0 },
-{"move",    "y,X",	0x6700, 0xff00, WR_y|RD_X, 	0,	0 },
-{"move",    "Y,Z",	0x6500, 0xff00, WR_Y|RD_Z,	0,	0 },
-{"mul",     "z,v,y",	0, (int) M_MUL, INSN_MACRO,	0,	0 },
-{"mult",    "x,y",	0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	0 },
-{"multu",   "x,y",	0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	0 },
-{"neg",	    "x,w",	0xe80b, 0xf81f, WR_x|RD_y,	0,	0 },
-{"not",	    "x,w",	0xe80f, 0xf81f, WR_x|RD_y,	0,	0 },
-{"or",	    "x,y",	0xe80d, 0xf81f, WR_x|RD_x|RD_y,	0,	0 },
-{"rem",     "0,x,y",	0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	0 },
-{"rem",     "z,v,y",	0, (int) M_REM_3, INSN_MACRO,	0,	0 },
-{"remu",    "0,x,y",	0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	0 },
-{"remu",    "z,v,y",	0, (int) M_REMU_3, INSN_MACRO,	0,	0 },
-{"sb",	    "y,5(x)",	0xc000, 0xf800, RD_y|RD_x,	0,	0 },
+{"mfhi",    "x",	0xe810, 0xf8ff, WR_x|RD_HI,	0,	I1 },
+{"mflo",    "x",	0xe812, 0xf8ff, WR_x|RD_LO,	0,	I1 },
+{"move",    "y,X",	0x6700, 0xff00, WR_y|RD_X, 	0,	I1 },
+{"move",    "Y,Z",	0x6500, 0xff00, WR_Y|RD_Z,	0,	I1 },
+{"mul",     "z,v,y",	0, (int) M_MUL, INSN_MACRO,	0,	I1 },
+{"mult",    "x,y",	0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
+{"multu",   "x,y",	0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
+{"neg",	    "x,w",	0xe80b, 0xf81f, WR_x|RD_y,	0,	I1 },
+{"not",	    "x,w",	0xe80f, 0xf81f, WR_x|RD_y,	0,	I1 },
+{"or",	    "x,y",	0xe80d, 0xf81f, WR_x|RD_x|RD_y,	0,	I1 },
+{"rem",     "0,x,y",	0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
+{"rem",     "z,v,y",	0, (int) M_REM_3, INSN_MACRO,	0,	I1 },
+{"remu",    "0,x,y",	0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
+{"remu",    "z,v,y",	0, (int) M_REMU_3, INSN_MACRO,	0,	I1 },
+{"sb",	    "y,5(x)",	0xc000, 0xf800, RD_y|RD_x,	0,	I1 },
 {"sd",	    "y,D(x)",	0x7800, 0xf800, RD_y|RD_x, 	0,	I3 },
 {"sd",	    "y,D(S)",	0xf900, 0xff00, RD_y|RD_PC, 	0,	I3 },
-{"sd",	    "R,C(S)",	0xfa00, 0xff00, RD_31|RD_PC,	0,	0 },
-{"sh",	    "y,H(x)",	0xc800, 0xf800, RD_y|RD_x,	0,	0 },
-{"sllv",    "y,x",	0xe804, 0xf81f, WR_y|RD_y|RD_x, 0,	0 },
-{"sll",	    "x,w,<",	0x3000, 0xf803, WR_x|RD_y,	0,	0 },
-{"sll",     "y,x",	0xe804, 0xf81f, WR_y|RD_y|RD_x,	0,	0 },
-{"slti",    "x,8",	0x5000, 0xf800, WR_T|RD_x,	0,	0 },
-{"slt",	    "x,y",	0xe802, 0xf81f, WR_T|RD_x|RD_y,	0,	0 },
-{"slt",     "x,8",	0x5000, 0xf800, WR_T|RD_x,	0,	0 },
-{"sltiu",   "x,8",	0x5800, 0xf800, WR_T|RD_x,	0,	0 },
-{"sltu",    "x,y",	0xe803, 0xf81f, WR_T|RD_x|RD_y,	0,	0 },
-{"sltu",    "x,8",	0x5800, 0xf800, WR_T|RD_x,	0,	0 },
-{"srav",    "y,x",	0xe807, 0xf81f, WR_y|RD_y|RD_x,	0,	0 },
-{"sra",	    "x,w,<",	0x3003, 0xf803, WR_x|RD_y,	0,	0 },
-{"sra",     "y,x",	0xe807, 0xf81f, WR_y|RD_y|RD_x,	0,	0 },
-{"srlv",    "y,x",	0xe806, 0xf81f, WR_y|RD_y|RD_x,	0,	0 },
-{"srl",	    "x,w,<",	0x3002, 0xf803, WR_x|RD_y,	0,	0 },
-{"srl",     "y,x",	0xe806, 0xf81f, WR_y|RD_y|RD_x,	0,	0 },
-{"subu",    "z,v,y",	0xe003, 0xf803, WR_z|RD_x|RD_y,	0,	0 },
-{"subu",    "y,x,4",	0, (int) M_SUBU_I, INSN_MACRO,	0,	0 },
-{"subu",    "x,k",	0, (int) M_SUBU_I_2, INSN_MACRO,0,	0 },
-{"sw",	    "y,W(x)",	0xd800, 0xf800, RD_y|RD_x,	0,	0 },
-{"sw",	    "x,V(S)",	0xd000, 0xf800, RD_x|RD_SP,	0,	0 },
-{"sw",	    "R,V(S)",	0x6200, 0xff00, RD_31|RD_SP,	0,	0 },
-{"xor",	    "x,y",	0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0,	0 },
+{"sd",	    "R,C(S)",	0xfa00, 0xff00, RD_31|RD_PC,	0,	I1 },
+{"sh",	    "y,H(x)",	0xc800, 0xf800, RD_y|RD_x,	0,	I1 },
+{"sllv",    "y,x",	0xe804, 0xf81f, WR_y|RD_y|RD_x, 0,	I1 },
+{"sll",	    "x,w,<",	0x3000, 0xf803, WR_x|RD_y,	0,	I1 },
+{"sll",     "y,x",	0xe804, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
+{"slti",    "x,8",	0x5000, 0xf800, WR_T|RD_x,	0,	I1 },
+{"slt",	    "x,y",	0xe802, 0xf81f, WR_T|RD_x|RD_y,	0,	I1 },
+{"slt",     "x,8",	0x5000, 0xf800, WR_T|RD_x,	0,	I1 },
+{"sltiu",   "x,8",	0x5800, 0xf800, WR_T|RD_x,	0,	I1 },
+{"sltu",    "x,y",	0xe803, 0xf81f, WR_T|RD_x|RD_y,	0,	I1 },
+{"sltu",    "x,8",	0x5800, 0xf800, WR_T|RD_x,	0,	I1 },
+{"srav",    "y,x",	0xe807, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
+{"sra",	    "x,w,<",	0x3003, 0xf803, WR_x|RD_y,	0,	I1 },
+{"sra",     "y,x",	0xe807, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
+{"srlv",    "y,x",	0xe806, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
+{"srl",	    "x,w,<",	0x3002, 0xf803, WR_x|RD_y,	0,	I1 },
+{"srl",     "y,x",	0xe806, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
+{"subu",    "z,v,y",	0xe003, 0xf803, WR_z|RD_x|RD_y,	0,	I1 },
+{"subu",    "y,x,4",	0, (int) M_SUBU_I, INSN_MACRO,	0,	I1 },
+{"subu",    "x,k",	0, (int) M_SUBU_I_2, INSN_MACRO,0,	I1 },
+{"sw",	    "y,W(x)",	0xd800, 0xf800, RD_y|RD_x,	0,	I1 },
+{"sw",	    "x,V(S)",	0xd000, 0xf800, RD_x|RD_SP,	0,	I1 },
+{"sw",	    "R,V(S)",	0x6200, 0xff00, RD_31|RD_SP,	0,	I1 },
+{"xor",	    "x,y",	0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0,	I1 },
   /* MIPS16e additions */
-{"jalrc",   "x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     0 },
-{"jalrc",   "R,x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     0 },
-{"jrc",     "x",	0xe880, 0xf8ff, RD_x|TRAP,	0,      0 },
-{"jrc",     "R",	0xe8a0, 0xffff, RD_31|TRAP,	0,      0 },
-{"restore", "M",	0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP,	0,	0 },
-{"save",    "m",	0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP,	0,	0 },
-{"sdbbp",   "6",	0xe801, 0xf81f, TRAP,		0,	0 },
-{"seb",	    "x",	0xe891, 0xf8ff, WR_x|RD_x,	0,      0 },
-{"seh",	    "x",	0xe8b1, 0xf8ff, WR_x|RD_x,	0,      0 },
-{"sew",	    "x",	0xe8d1, 0xf8ff, WR_x|RD_x,	0,      I3 },
-{"zeb",	    "x",	0xe811, 0xf8ff, WR_x|RD_x,	0,      0 },
-{"zeh",	    "x",	0xe831, 0xf8ff, WR_x|RD_x,	0,      0 },
-{"zew",	    "x",	0xe851, 0xf8ff, WR_x|RD_x,	0,      I3 },
+{"jalrc",   "x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     I32 },
+{"jalrc",   "R,x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     I32 },
+{"jrc",     "x",	0xe880, 0xf8ff, RD_x|TRAP,	0,      I32 },
+{"jrc",     "R",	0xe8a0, 0xffff, RD_31|TRAP,	0,      I32 },
+{"restore", "M",	0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP,	0,	I32 },
+{"save",    "m",	0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP,	0,	I32 },
+{"sdbbp",   "6",	0xe801, 0xf81f, TRAP,		0,	I32 },
+{"seb",	    "x",	0xe891, 0xf8ff, WR_x|RD_x,	0,      I32 },
+{"seh",	    "x",	0xe8b1, 0xf8ff, WR_x|RD_x,	0,      I32 },
+{"sew",	    "x",	0xe8d1, 0xf8ff, WR_x|RD_x,	0,      I64 },
+{"zeb",	    "x",	0xe811, 0xf8ff, WR_x|RD_x,	0,      I32 },
+{"zeh",	    "x",	0xe831, 0xf8ff, WR_x|RD_x,	0,      I32 },
+{"zew",	    "x",	0xe851, 0xf8ff, WR_x|RD_x,	0,      I64 },
 };
 
 const int bfd_mips16_num_opcodes =